2048 小游戏

一.主要功能:

  1. 游戏初始化:新建游戏4×4的16宫格画布,随机格子上生成2或者4两个数字
  2. 格子的移动:先判断能否移动,移动后判断能否合并,合并后改变格子颜色和数字
  3. 新格子的生成:移动一次,就在剩余的空格子中随机生成一个2或者4
  4. 判赢:16宫格中合并出了“2048”则为游戏胜利
  5. 判输:16宫格中没有剩余空格子且不能再向任何方向移动则为游戏失败

二.项目的主要结构:

在项目2018游戏中,有4个源文件,此外,还有3个.png和两个.wav格式的音乐文件。一个音乐是按键移动的声音,另外一个是碰撞后的消除的声音。然后游戏的最高分保存是在Recording源文件中,之后附上所需的图片文件和音乐文件:

来了来了,

三.代码

  1. Game.java
package shixun;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
public class Game extends JFrame {private static final long serialVersionUID = 1L;public static void main(String[] args) {Game UI = new Game();UI.IntUI();}// 用于存放数据的数组,构成游戏4*4界面的数值private int Numbers[][] = new int[4][4] ;private void IntUI() {this.setTitle("2048小游戏");this.setLocation(450, 100);this.setSize(400, 500);this.setLayout(null);// 开始游戏按钮ImageIcon imgicon = new ImageIcon("res/start.png");JButton bt = new JButton(imgicon);bt.setFocusable(false);bt.setBorderPainted(false);bt.setFocusPainted(false);bt.setContentAreaFilled(false);bt.setBounds(5, 10, 120, 30);// 设置按钮的x,y坐标位置和宽度与高度this.add(bt);//后退一步按钮ImageIcon backicon = new ImageIcon("res/backicon.png");JButton back = new JButton(backicon);back.setFocusable(false);back.setBorderPainted(false);back.setFocusPainted(false);back.setContentAreaFilled(false);back.setBounds(270, 10, 120, 30);// 设置按钮的x,y坐标位置和宽度与高度this.add(back);// 关于按钮ImageIcon imgicon2 = new ImageIcon("res/about.png");JButton about = new JButton(imgicon2);about.setFocusable(false);about.setBorderPainted(false);about.setFocusPainted(false);about.setContentAreaFilled(false);about.setBounds(160, 10, 70, 30);this.add(about);// 分数显示JLabel lb = new JLabel("分数:0");lb.setBounds(40, 45, 120, 30);lb.setFont(new Font("幼圆", Font.CENTER_BASELINE, 18));lb.setForeground(new Color(0x000000));this.add(lb);//最高分数Recorder.getRecording();int maxscore = Recorder.getMaxscore_2048();JLabel M=new JLabel("最高分:0");M.setBounds(150,45,120,30);M.setFont(new Font("幼圆", Font.CENTER_BASELINE, 18));M.setForeground(new Color(0x000000));this.add(M);//静音JCheckBox isSoundBox=new JCheckBox("静音");isSoundBox.setBounds(290, 45, 120, 30);isSoundBox.setFont(new Font("幼圆", Font.CENTER_BASELINE, 18));isSoundBox.setFocusable(false);isSoundBox.setBorderPainted(false);isSoundBox.setFocusPainted(false);isSoundBox.setContentAreaFilled(false);this.add(isSoundBox);this.setDefaultCloseOperation(3);this.setResizable(false);this.setVisible(true);// 显示界面// 创建事件处理类MyListener cl = new MyListener(this,Numbers,lb,M, bt, about,back,isSoundBox);bt.addActionListener(cl);about.addActionListener(cl);back.addActionListener(cl);isSoundBox.addActionListener(cl);this.addKeyListener(cl);}
// 重写窗体@Override
public void paint(Graphics g) {super.paint(g);g.setColor(new Color(0xBBADA0));g.fillRoundRect(15, 110, 370, 370, 15, 15);// 大矩形框g.setColor(new Color(0xCDC1B4));for (int i = 0; i < 4; i++) {for (int j = 0; j < 4; j++) {g.fillRoundRect(25 + i * 90, 120 + j * 90, 80, 80, 15, 15);// 小矩形框}}// 调整数字的位置并上色for (int i = 0; i < 4; i++) {for (int j = 0; j < 4; j++) {if (Numbers[j][i] != 0) {int FontSize = 30;int MoveX = 0, MoveY = 0;switch (Numbers[j][i]) {case 2:g.setColor(new Color(0xeee4da));FontSize = 30;MoveX = 0;MoveY = 0;break;case 4:g.setColor(new Color(0xede0c8));FontSize = 30;MoveX = 0;MoveY = 0;break;case 8:g.setColor(new Color(0xf2b179));FontSize = 30;MoveX = 0;MoveY = 0;break;case 16:g.setColor(new Color(0xf59563));FontSize = 29;MoveX = -5;MoveY = 0;break;case 32:g.setColor(new Color(0xf67c5f));FontSize = 29;MoveX = -5;MoveY = 0;break;case 64:g.setColor(new Color(0xf65e3b));FontSize = 29;MoveX = -5;MoveY = 0;break;case 128:g.setColor(new Color(0xedcf72));FontSize = 28;MoveX = -10;MoveY = 0;break;case 256:g.setColor(new Color(0xedcc61));FontSize = 28;MoveX = -10;MoveY = 0;break;case 512:g.setColor(new Color(0xedc850));FontSize = 28;MoveX = -10;MoveY = 0;break;case 1024:g.setColor(new Color(0xedc53f));FontSize = 27;MoveX = -15;MoveY = 0;break;case 2048:g.setColor(new Color(0xedc22e));FontSize = 27;MoveX = -15;MoveY = 0;break;default:g.setColor(new Color(0x000000));break;}g.fillRoundRect(25 + i * 90, 120 + j * 90, 80, 80, 15, 15);// 小矩形框上色g.setColor(new Color(0x000000));g.setFont(new Font("Kristen ITC", Font.PLAIN, FontSize));g.drawString(Numbers[j][i] + "", 25 + i * 90 + 30 + MoveX,120 + j * 90 + 50 + MoveY);}}}}
}

2.MyListener.java

package shixun;
import java.awt.Component;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.util.Arrays;
import java.util.Random;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
public class MyListener extends KeyAdapter implements ActionListener {/*** KevinWu*/private Game UI;// 界面对象private int Numbers[][];// 存放数据的数组private Random rand = new Random();private int BackUp[][]= new int[4][4];//用于备份数组,供回退时使用private int BackUp2[][]= new int[4][4];//用于备份数组,供起死回生时使用public JLabel lb;public JLabel M;int score = 0;int maxscore=Recorder.getMaxscore_2048();int tempscore,tempscore2;//记录回退isWin的分数值public JButton bt,about,back;public JCheckBox isSoundBox;private boolean isWin=false,relive=false,hasBack=false,isSound=true;public MyListener(Game UI, int Numbers[][], JLabel lb,JLabel M ,JButton bt,JButton about,JButton back,JCheckBox isSoundBox) {this.UI = UI;this.Numbers = Numbers;this.lb = lb;this.bt=bt;this.about=about;this.back=back;this.isSoundBox=isSoundBox;this.M=M;}@Overridepublic void actionPerformed(ActionEvent e) {// TODO Auto-generated method stubif(e.getSource() ==bt ){isWin=false;for (int i = 0; i < 4; i++)for (int j = 0; j < 4; j++)Numbers[i][j] = 0;
score = 0;// 保证每次重置游戏都是0分开始lb.setText("分数:" + score);M.setText("最高分:"+maxscore);int r1 = rand.nextInt(4);int r2 = rand.nextInt(4);int c1 = rand.nextInt(4);int c2 = rand.nextInt(4);while (r1 == r2 && c1 == c2) {r2 = rand.nextInt(4);c2 = rand.nextInt(4);}// 生成数字(2或者4)int value1 = rand.nextInt(2) * 2 + 2;int value2 = rand.nextInt(2) * 2 + 2;// 把数字存进对应的位置Numbers[r1][c1] = value1;Numbers[r2][c2] = value2;UI.paint(UI.getGraphics());}else if(e.getSource()==about){JOptionPane.showMessageDialog(UI, "游戏规则:\n"+ "开始时棋盘内随机出现两个数字,出现的数字仅可能为2或4\n"+ "玩家可以选择上下左右四个方向,若棋盘内的数字出现位移或合并,视为有效移动\n"+ "玩家选择的方向上若有相同的数字则合并,每次有效移动可以同时合并,但不可以连续合并\n"+ "合并所得的所有新生成数字想加即为该步的有效得分\n"+ "玩家选择的方向行或列前方有空格则出现位移\n"+ "每有效移动一步,棋盘的空位(无数字处)随机出现一个数字(依然可能为2或4)\n"+ "棋盘被数字填满,无法进行有效移动,判负,游戏结束\n"+ "棋盘上出现2048,判胜,游戏结束。\n");}else if(e.getSource()==back&&hasBack==false){hasBack=true;if(relive==false){score=tempscore;lb.setText("分数:" + score);for(int i=0;i<BackUp.length;i++){Numbers[i]=Arrays.copyOf(BackUp[i], BackUp[i].length);}}else{score=tempscore2;lb.setText("分数:" + score);for(int i=0;i<BackUp2.length;i++){Numbers[i]=Arrays.copyOf(BackUp2[i], BackUp2[i].length);}relive=false;}UI.paint(UI.getGraphics()); }else if(e.getSource().equals(isSoundBox)){if (isSoundBox.isSelected())isSound=false;elseisSound=true;}}// 键盘监听public void keyPressed(KeyEvent event) {int Counter = 0;// 计算器,判断是否移动了int NumCounter = 0;// 用于统计整个大方框中数字的个数,判断是否已满int NumNearCounter = 0;// 用于统计相邻格子数字相同的个数/** 方向键键值:左:37上:38右:39下:40*/hasBack = false;if (BackUp != null || BackUp.length != 0) {tempscore2 = tempscore;// 先把分数备份好// 下面的for循环调用java.util.Arrays.copyOf()方法复制数组,实现备份for (int i = 0; i < BackUp.length; i++) {BackUp2[i] = Arrays.copyOf(BackUp[i], BackUp[i].length);}}tempscore = score;// 先把分数备份好// 下面的for循环调用java.util.Arrays.copyOf()方法复制数组,实现备份for (int i = 0; i < Numbers.length; i++) {BackUp[i] = Arrays.copyOf(Numbers[i], Numbers[i].length);}if (isWin == false) {switch (event.getKeyCode()) {case 37:// 向左移动if (isSound == true)new PlaySound("move.wav").start();for (int h = 0; h < 4; h++)for (int l = 0; l < 4; l++)if (Numbers[h][l] != 0) {int temp = Numbers[h][l];int pre = l - 1;while (pre >= 0 && Numbers[h][pre] == 0) {Numbers[h][pre] = temp;Numbers[h][pre + 1] = 0;pre--;Counter++;}}for (int h = 0; h < 4; h++)for (int l = 0; l < 4; l++)if (l + 1 < 4&& (Numbers[h][l] == Numbers[h][l + 1])&& (Numbers[h][l] != 0 || Numbers[h][l + 1] != 0)) {if (isSound == true)new PlaySound("merge.wav").start();Numbers[h][l] = Numbers[h][l] + Numbers[h][l + 1];Numbers[h][l + 1] = 0;Counter++;score += Numbers[h][l];if (Numbers[h][l] == 2048) {isWin = true;}}
for (int h = 0; h < 4; h++)for (int l = 0; l < 4; l++)if (Numbers[h][l] != 0) {int temp = Numbers[h][l];int pre = l - 1;while (pre >= 0 && Numbers[h][pre] == 0) {Numbers[h][pre] = temp;Numbers[h][pre + 1] = 0;pre--;Counter++;}}break;case 39:// 向右移动if (isSound == true)new PlaySound("move.wav").start();for (int h = 3; h >= 0; h--)for (int l = 3; l >= 0; l--)if (Numbers[h][l] != 0) {int temp = Numbers[h][l];int pre = l + 1;while (pre <= 3 && Numbers[h][pre] == 0) {Numbers[h][pre] = temp;Numbers[h][pre - 1] = 0;pre++;Counter++;}}for (int h = 3; h >= 0; h--)for (int l = 3; l >= 0; l--)if (l + 1 < 4&& (Numbers[h][l] == Numbers[h][l + 1])&& (Numbers[h][l] != 0 || Numbers[h][l + 1] != 0)) {if (isSound == true)new PlaySound("merge.wav").start();Numbers[h][l + 1] = Numbers[h][l]+ Numbers[h][l + 1];Numbers[h][l] = 0;Counter++;score += Numbers[h][l + 1];if (Numbers[h][l + 1] == 2048) {isWin = true;}}for (int h = 3; h >= 0; h--)for (int l = 3; l >= 0; l--)if (Numbers[h][l] != 0) {int temp = Numbers[h][l];int pre = l + 1;while (pre <= 3 && Numbers[h][pre] == 0) {Numbers[h][pre] = temp;Numbers[h][pre - 1] = 0;pre++;Counter++;}}break;case 38://向上移动if (isSound == true)new PlaySound("move.wav").start();for (int l = 0; l < 4; l++)for (int h = 0; h < 4; h++)if (Numbers[h][l] != 0) {int temp = Numbers[h][l];int pre = h - 1;while (pre >= 0 && Numbers[pre][l] == 0) {Numbers[pre][l] = temp;Numbers[pre + 1][l] = 0;pre--;Counter++;}}for (int l = 0; l < 4; l++)for (int h = 0; h < 4; h++)if (h + 1 < 4&& (Numbers[h][l] == Numbers[h + 1][l])&& (Numbers[h][l] != 0 || Numbers[h + 1][l] != 0)) {if (isSound == true)new PlaySound("merge.wav").start();Numbers[h][l] = Numbers[h][l] + Numbers[h + 1][l];Numbers[h + 1][l] = 0;Counter++;score += Numbers[h][l];if (Numbers[h][l] == 2048) {isWin = true;}}for (int l = 0; l < 4; l++)for (int h = 0; h < 4; h++)if (Numbers[h][l] != 0) {int temp = Numbers[h][l];int pre = h - 1;while (pre >= 0 && Numbers[pre][l] == 0) {Numbers[pre][l] = temp;Numbers[pre + 1][l] = 0;pre--;Counter++;}}break;case 40:// 向下移动if (isSound == true)new PlaySound("move.wav").start();for (int l = 3; l >= 0; l--)for (int h = 3; h >= 0; h--)if (Numbers[h][l] != 0) {int temp = Numbers[h][l];int pre = h + 1;while (pre <= 3 && Numbers[pre][l] == 0) {Numbers[pre][l] = temp;Numbers[pre - 1][l] = 0;pre++;Counter++;}}for (int l = 3; l >= 0; l--)for (int h = 3; h >= 0; h--)if (h + 1 < 4&& (Numbers[h][l] == Numbers[h + 1][l])&& (Numbers[h][l] != 0 || Numbers[h + 1][l] != 0)) {if (isSound == true)new PlaySound("merge.wav").start();Numbers[h + 1][l] = Numbers[h][l]+ Numbers[h + 1][l];Numbers[h][l] = 0;Counter++;score += Numbers[h + 1][l];if (Numbers[h + 1][l] == 2048) {isWin = true;}}for (int l = 0; l < 4; l++)for (int h = 0; h < 4; h++)if (Numbers[h][l] != 0) {int temp = Numbers[h][l];int pre = h - 1;while (pre >= 0 && Numbers[pre][l] == 0) {Numbers[pre][l] = temp;Numbers[pre + 1][l] = 0;pre--;Counter++;}}break;
case 40:// 向下移动if (isSound == true)new PlaySound("move.wav").start();for (int l = 3; l >= 0; l--)for (int h = 3; h >= 0; h--)if (Numbers[h][l] != 0) {int temp = Numbers[h][l];int pre = h + 1;while (pre <= 3 && Numbers[pre][l] == 0) {Numbers[pre][l] = temp;Numbers[pre - 1][l] = 0;pre++;Counter++;}}for (int l = 3; l >= 0; l--)for (int h = 3; h >= 0; h--)if (h + 1 < 4&& (Numbers[h][l] == Numbers[h + 1][l])&& (Numbers[h][l] != 0 || Numbers[h + 1][l] != 0)) {if (isSound == true)new PlaySound("merge.wav").start();Numbers[h + 1][l] = Numbers[h][l]+ Numbers[h + 1][l];Numbers[h][l] = 0;Counter++;score += Numbers[h + 1][l];if (Numbers[h + 1][l] == 2048) {isWin = true;}}for (int l = 3; l >= 0; l--)for (int h = 3; h >= 0; h--)if (Numbers[h][l] != 0) {int temp = Numbers[h][l];int pre = h + 1;while (pre <= 3 && Numbers[pre][l] == 0) {Numbers[pre][l] = temp;Numbers[pre - 1][l] = 0;pre++;Counter++;}}break;
default:break;
}if(maxscore<=score) {maxscore=score;Recorder.setMaxscore(maxscore);Recorder.keepRecording();}for (int i = 0; i < 3; i++) {for (int j = 0; j < 3; j++) {if (Numbers[i][j] == Numbers[i][j + 1]&& Numbers[i][j] != 0) {NumNearCounter++;}if (Numbers[i][j] == Numbers[i + 1][j]&& Numbers[i][j] != 0) {NumNearCounter++;}if (Numbers[3][j] == Numbers[3][j + 1]&& Numbers[3][j] != 0) {NumNearCounter++;}if (Numbers[i][3] == Numbers[i + 1][3]&& Numbers[i][3] != 0) {NumNearCounter++;}}}for (int i = 0; i < 4; i++) {for (int j = 0; j < 4; j++) {if (Numbers[i][j] != 0) {NumCounter++;}}}if (Counter > 0) {lb.setText("分数:" + score);M.setText("最高分:"+maxscore);int r1 = rand.nextInt(4);int c1 = rand.nextInt(4);while (Numbers[r1][c1] != 0) {r1 = rand.nextInt(4);c1 = rand.nextInt(4);}int value1 = rand.nextInt(2) * 2 + 2;Numbers[r1][c1] = value1;}
if (isWin == true){UI.paint(UI.getGraphics());JOptionPane.showMessageDialog(UI, "恭喜你赢了!\n您的最终得分为:" + score);}if (NumCounter == 16 && NumNearCounter == 0) {relive = true;JOptionPane.showMessageDialog(UI, "没地方可以合并咯!!"+ "\n很遗憾,您输了~>_<~" + "\n悄悄告诉你,游戏有起死回生功能哦,不信你“退一步”试试?"+ "\n说不定能扭转乾坤捏 (^_~)");}UI.paint(UI.getGraphics());}}}  

3.PlaySound.java

package shixun;
import java.io.File;
import java.io.IOException;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.SourceDataLine;
//播放声音的线程
public class PlaySound extends Thread {private String filename;public PlaySound(String wavfile) {filename = "res/" + wavfile;}public void run() {File soundFile = new File(filename);AudioInputStream audioInputStream = null;try {audioInputStream = AudioSystem.getAudioInputStream(soundFile);} catch (Exception e1) {e1.printStackTrace();return;}AudioFormat format = audioInputStream.getFormat();SourceDataLine auline = null;DataLine.Info info = new DataLine.Info(SourceDataLine.class, format);try {auline = (SourceDataLine) AudioSystem.getLine(info);auline.open(format);} catch (Exception e) {e.printStackTrace();return;}auline.start();int nBytesRead = 0;// 这是缓冲byte[] abData = new byte[512];try {while (nBytesRead != -1) {nBytesRead = audioInputStream.read(abData, 0, abData.length);if (nBytesRead >= 0)auline.write(abData, 0, nBytesRead);}} catch (IOException e) {e.printStackTrace();return;} finally {auline.drain();auline.close();}}
}

4.Recorder.java

package shixun;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
public  class Recorder {private static int maxscore_2048=0;public static int  getMaxscore_2048() {// TODO Auto-generated method stubreturn maxscore_2048;}public static void setMaxscore(int maxscore_2048) {// TODO Auto-generated method stubRecorder.maxscore_2048=maxscore_2048;}private static FileReader fr=null;
private static BufferedReader br=null;
private static FileWriter fw=null;
private static BufferedWriter bw=null;
//从文件中读取,记录
public static void getRecording()
{boolean flag =false;//判断文件是否新建try {File f=new File("src/myRecording.txt");if(f.exists()){ fr=new FileReader(f);br=new BufferedReader(fr);String n=br.readLine();maxscore_2048=Integer.parseInt(n); }else {flag=f.createNewFile();}}catch(Exception e) {e.printStackTrace();}finally {try {if(!flag) {br.close();fr.close();}}catch(Exception e2) {e2.printStackTrace();}}}//保存最高分记录public static void keepRecording(){try {File f=new File("src/myRecording.txt");fw=new FileWriter(f);bw=new BufferedWriter(fw);bw.write(maxscore_2048+"\r\n");}catch(IOException e) {e.printStackTrace();}finally {try {bw.close();fw.close();}catch(IOException e) {e.printStackTrace();}}}} 

四.游戏截图

写到这,不容易,留个赞吧,谢谢!

Java2048游戏源代码相关推荐

  1. flappy bird游戏源代码揭秘和下载后续---移植到android真机上

    前言:         上一篇博客 flappy bird游戏源代码揭秘和下载,源码是运行在window或者mac系统上的,现在我们需要把代码移植到android真机上,让小鸟在手机里飞起来! ps: ...

  2. c语言红警源代码,真香!红警游戏源代码开源了,70,80,90最好的游戏

    原标题:真香!红警游戏源代码开源了,70,80,90最好的游戏 来自:网络 | 责编:乐乐 程序员小乐(ID:study_tech)第 895 次推文 图源:百度 往日回顾:重磅!世界上最好的编程语言 ...

  3. python双手打字_Python打字练习小游戏源代码

    Python打字练习小游戏源代码 Python代码狂人 Python代码大全 Python打字练习小游戏源程序,随机产生一串字符,可对打字练习的正确率和时间进行统计,运行截图如下: from tkin ...

  4. 跳一跳改分java源码_解密微信小程序漏洞:可下载任意小游戏源代码,“跳一跳”可改分...

    原标题:解密微信小程序漏洞:可下载任意小游戏源代码,"跳一跳"可改分 雷锋网消息,据 IT 之家 1 月 2 日消息称,"跳一跳"居然可以利用漏洞自己改分数,甚 ...

  5. 推箱子游戏 java源代码_java推箱子游戏源代码(含推箱子的判断)

    <java推箱子游戏源代码(含推箱子的判断)>由会员分享,可在线阅读,更多相关<java推箱子游戏源代码(含推箱子的判断)(6页珍藏版)>请在人人文库网上搜索. 1.第一个Ja ...

  6. 一个简单的游戏源代码

    一个简单的游戏源代码 作者:陈跃峰 出自: http://blog.csdn.net/mailbomb 实现一个简单的翻牌游戏,每次最多翻开两个数字,如果数字相同则消失,否则两个数字不显示,可以继续游 ...

  7. flappy bird游戏源代码揭秘和下载后续---移植到html5网页浏览器

    前言:      我们分析了flappy bird的代码思路(flappy bird游戏源代码揭秘和下载),也移植到了android平台(flappy bird游戏源代码揭秘和下载后续---移植到an ...

  8. Beat #39;Em Up Game Starter Kit (横版格斗游戏) cocos2d-x游戏源代码

    浓缩精华.专注战斗! 游戏的本质是什么?界面?养成?NoNo!    游戏来源于对实战和比赛的模拟,所以它的本源就是对抗.就是战斗! 是挥洒热血的一种方式! 一个游戏最复杂最难做的是什么?UI?商城? ...

  9. c语言大作业黑白棋,C语言编写黑白棋游戏源代码.doc

    C语言编写的黑白棋游戏源代码 /*3.3.4 源程序*/ #include "graphics.h" /*图形系统头文件*/ #define LEFT 0x4b00 /*光标左键值 ...

  10. 一款使用JavaScript实现的篮球投篮游戏源代码,在浏览器里就能玩的篮球小游戏代码

    一款使用JavaScript实现的篮球投篮游戏源代码,在浏览器里就能玩的篮球小游戏代码 -根据光标的移动,沿某个方向击球 -球改变大小以使体验像3D一样 -音效让体验像真实生活! -球与轮辋碰撞并反弹 ...

最新文章

  1. firefox下几个实用的免费开发插件
  2. IIS6.0 日期格式问题
  3. SQL注入不能多句执行时的一种突破方法(SA权限)
  4. 【VLC-Android】Mac下编译vlc-android
  5. java 内部thread_Java代码质量改进之:使用ThreadLocal维护线程内部变量
  6. 简述C++程序编写的过程
  7. 为了减少接口的响应时间,有哪些优化措施?(可以从架构、代码等各个角度谈)?
  8. java puzzlers英文版_java puzzlers [更新至14.04.03]
  9. socket.h中定义的函数
  10. 华为tftp服务器如何配置文件,配置tftp服务器
  11. android与相机连接电脑,使用Android手机或平板电脑控制dSLR相机
  12. Win10自带微软输入法消失解决办法(无法显示输入法图标)
  13. 数据报表开发技巧:自动为数据报表添加【小计】、【总计】行
  14. Arxiv 2022|NoPe-NeRF:优化无位姿先验的神经辐射场
  15. 服务器状态监控app,服务器/网站连接状态监控工具
  16. 【Python】破解摩斯密码
  17. 2022 高教杯数学建模C题古代玻璃制品的成分分析与鉴别回顾及总结
  18. java做网站需要什么_java怎么做网站?java做网站要掌握哪些技术?
  19. matlab 大小写转换
  20. Linux 下python文件多行注释的方法

热门文章

  1. SeaWeedFS文件存储服务器搭建
  2. springboot整合quartz定时任务
  3. 听完蔡学镛的分享《不瞌睡的PPT制作秘诀》后的总结
  4. shader基础学习摘要(一)
  5. donet 微服务开发 学习-consul 服务端Api开发
  6. Java观察者模式例子
  7. 如何使用XShell将本机文件上传到虚拟机上?
  8. 【新书推荐】【2021】基于多源信息融合的航天器自主导航技术
  9. Unity 模拟鼠标自动点击事件
  10. 快速打造 Android 自定义表情库