大橙子网站建设,新征程启航
为企业提供网站建设、域名注册、服务器等服务
J2ME贪吃蛇源代码——200行左右,包含详细注释 package snake;import javax.microedition.midlet.*;
昭平网站制作公司哪家好,找创新互联!从网页设计、网站建设、微信开发、APP开发、成都响应式网站建设等网站项目制作,到程序开发,运营维护。创新互联自2013年创立以来到现在10年的时间,我们拥有了丰富的建站经验和运维经验,来保证我们的工作的顺利进行。专注于网站建设就选创新互联。
import javax.microedition.lcdui.*;public class SnakeMIDlet extends MIDlet {
SnakeCanvas displayable = new SnakeCanvas();
public SnakeMIDlet() {
Display.getDisplay(this).setCurrent(displayable);
}public void startApp() {}public void pauseApp() {}public void destroyApp(boolean unconditional) {}}//文件名:SnakeCanvas.javapackage snake;import java.util.*;
import javax.microedition.lcdui.*;/**
* 贪吃蛇游戏
*/
public class SnakeCanvas extends Canvas implements Runnable{
/**存储贪吃蛇节点坐标,其中第二维下标为0的代表x坐标,第二维下标是1的代表y坐标*/
int[][] snake = new int[200][2];
/**已经使用的节点数量*/
int snakeNum;
/**贪吃蛇运动方向,0代表向上,1代表向下,2代表向左,3代表向右*/
int direction;
/*移动方向*/
/**向上*/
private final int DIRECTION_UP = 0;
/**向下*/
private final int DIRECTION_DOWN = 1;
/**向左*/
private final int DIRECTION_LEFT = 2;
/**向右*/
private final int DIRECTION_RIGHT = 3;/**游戏区域宽度*/
int width;
/**游戏区域高度*/
int height;/**蛇身单元宽度*/
private final byte SNAKEWIDTH = 4;/**是否处于暂停状态,true代表暂停*/
boolean isPaused = false;
/**是否处于运行状态,true代表运行*/
boolean isRun = true;/**时间间隔*/
private final int SLEEP_TIME = 300;
/**食物的X坐标*/
int foodX;
/**食物的Y坐标*/
int foodY;
/**食物的闪烁控制*/
boolean b = true;
/**Random对象*/
Random random = new Random();
public SnakeCanvas() {
//初始化
init();
width = this.getWidth();
height = this.getHeight();
//启动线程
new Thread(this).start();
}/**
* 初始化开始数据
*/
private void init(){
//初始化节点数量
snakeNum = 7;
//初始化节点数据
for(int i = 0;i snakeNum;i++){
snake[i][0] = 100 - SNAKEWIDTH * i;
snake[i][1] = 40;
}
//初始化移动方向
direction = DIRECTION_RIGHT;
//初始化食物坐标
foodX = 100;
foodY = 100;
}protected void paint(Graphics g) {
//清屏
g.setColor(0xffffff);
g.fillRect(0,0,width,height);
g.setColor(0);//绘制蛇身
for(int i = 0;i snakeNum;i++){
g.fillRect(snake[i][0],snake[i][1],SNAKEWIDTH,SNAKEWIDTH);
}
//绘制食物
if(b){
g.fillRect(foodX,foodY,SNAKEWIDTH,SNAKEWIDTH);
}
}private void move(int direction){
//蛇身移动
for(int i = snakeNum - 1;i 0;i--){
snake[i][0] = snake[i - 1][0];
snake[i][1] = snake[i - 1][1];
}//第一个单元格移动
switch(direction){
case DIRECTION_UP:
snake[0][1] = snake[0][1] - SNAKEWIDTH;
break;
case DIRECTION_DOWN:
snake[0][1] = snake[0][1] + SNAKEWIDTH;
break;
case DIRECTION_LEFT:
snake[0][0] = snake[0][0] - SNAKEWIDTH;
break;
case DIRECTION_RIGHT:
snake[0][0] = snake[0][0] + SNAKEWIDTH;
break;
}
}
/**
* 吃掉食物,自身增长
*/
private void eatFood(){
//判别蛇头是否和食物重叠
if(snake[0][0] == foodX snake[0][1] == foodY){
snakeNum++;
generateFood();
}
}
/**
* 产生食物
* 说明:食物的坐标必须位于屏幕内,且不能和蛇身重合
*/
private void generateFood(){
while(true){
foodX = Math.abs(random.nextInt() % (width - SNAKEWIDTH + 1))
/ SNAKEWIDTH * SNAKEWIDTH;
foodY = Math.abs(random.nextInt() % (height - SNAKEWIDTH + 1))
/ SNAKEWIDTH * SNAKEWIDTH;
boolean b = true;
for(int i = 0;i snakeNum;i++){
if(foodX == snake[i][0] snake[i][1] == foodY){
b = false;
break;
}
}
if(b){
break;
}
}
}
/**
* 判断游戏是否结束
* 结束条件:
* 1、蛇头超出边界
* 2、蛇头碰到自身
*/
private boolean isGameOver(){
//边界判别
if(snake[0][0] 0 || snake[0][0] (width - SNAKEWIDTH) ||
snake[0][1] 0 || snake[0][1] (height - SNAKEWIDTH)){
return true;
}
//碰到自身
for(int i = 4;i snakeNum;i++){
if(snake[0][0] == snake[i][0]
snake[0][1] == snake[i][1]){
return true;
}
}
return false;
}/**
* 事件处理
*/
public void keyPressed(int keyCode){
int action = this.getGameAction(keyCode);
//改变方向
switch(action){
case UP:
if(direction != DIRECTION_DOWN){
direction = DIRECTION_UP;
}
break;
case DOWN:
if(direction != DIRECTION_UP){
direction = DIRECTION_DOWN;
}
break;
case LEFT:
if(direction != DIRECTION_RIGHT){
direction = DIRECTION_LEFT;
}
break;
case RIGHT:
if(direction != DIRECTION_LEFT){
direction = DIRECTION_RIGHT;
}
break;
case FIRE:
//暂停和继续
isPaused = !isPaused;
break;
}
}/**
* 线程方法
* 使用精确延时
*/
public void run(){
try{
while (isRun) {
//开始时间
long start = System.currentTimeMillis();
if(!isPaused){
//吃食物
eatFood();
//移动
move(direction);
//结束游戏
if(isGameOver()){
break;
}
//控制闪烁
b = !b;
}
//重新绘制
repaint();
long end = System.currentTimeMillis();
//延时
if(end - start SLEEP_TIME){
Thread.sleep(SLEEP_TIME - (end - start));
}
}
}catch(Exception e){}
}
}
/**
* MVC模式中得Viewer,只负责对数据的显示,而不用理会游戏的控制逻辑
*/
class SnakeView implements Observer {
SnakeControl control = null; //实例话一个SnakeControl对象是control ..SnakeControl在jdk中不存在可能是第3方的或者是自己编写的一个类吧
SnakeModel model = null;//如上
JFrame mainFrame; //创建一个面板类jframe
Canvas paintCanvas;
/**
*Canvas 组件表示屏幕上一个空白矩形区域,应用程序可以在该区域内绘图,或者可以从该区域捕获用户的输入事件。
*应用程序必须为 Canvas 类创建子类,以获得有用的功能(如创建自定义组件)。必须重写 paint 方法,以便在 canvas 上执行自定义图形。
*/
JLabel labelScore;//....不说了吧..
public static final int canvasWidth = 200; //常量宽度200
public static final int canvasHeight = 300;//常量高300
public static final int nodeWidth = 10;//常量宽度10
public static final int nodeHeight = 10;//常量高度10
public SnakeView(SnakeModel model, SnakeControl control) {
this.model = model;
this.control = control;
mainFrame = new JFrame("GreedSnake");//创建jframe 标题是GreedSnake
Container cp = mainFrame.getContentPane(); //得到jfram的容器
labelScore = new JLabel("Score:"); //创建jlabel 标签内容是"Score:"
cp.add(labelScore, BorderLayout.NORTH);/将jlabel添加到jfram的容器中去
paintCanvas = new Canvas(); //创建新绘图区
paintCanvas.setSize(canvasWidth + 1, canvasHeight + 1); //设置绘图区大小
paintCanvas.addKeyListener(control);//添加键盘监听器control
cp.add(paintCanvas, BorderLayout.CENTER);//将绘图区添加到jfram容器中去.布局是BorderLayout的CENTER位置.就是东西南北中的中间
JPanel panelButtom = new JPanel();//创建一个panel
panelButtom.setLayout(new BorderLayout());//设置布局是BorderLayout
JLabel labelHelp;//标签的创建和添加开始了.......new了3遍就是实例化了3个都加到了panle的中间 ,标签的内容都是""中间的
labelHelp = new JLabel("PageUp, PageDown for speed;", JLabel.CENTER);
panelButtom.add(labelHelp, BorderLayout.NORTH);
labelHelp = new JLabel("ENTER or R or S for start;", JLabel.CENTER);
panelButtom.add(labelHelp, BorderLayout.CENTER);
labelHelp = new JLabel("SPACE or P for pause", JLabel.CENTER);
panelButtom.add(labelHelp, BorderLayout.SOUTH);
cp.add(panelButtom, BorderLayout.SOUTH);//把这个panel添加到jframe的容器里面去
mainFrame.addKeyListener(control);//为jframe添加键盘监听器
mainFrame.pack();//调整此窗口的大小,以适合其子组件的首选大小和布局。如果该窗口和/或其所有者仍不可显示,则两者在计算首选大小之前变得可显示。在计算首选大小之后,将会验证该 Window。
mainFrame.setResizable(false);//设置此 frame 是否可由用户调整大小。false就是不能
mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//点击又上角的就是关闭
mainFrame.setVisible(true);//设置jfram为能看到
}
void repaint() {
Graphics g = paintCanvas.getGraphics();//Graphics详细看jdk文档..我就知道是一个所有图形上下文的抽象基类..这里应该是那个画图面板
g.setColor(Color.WHITE);//设置这个颜色
g.fillRect(0, 0, canvasWidth, canvasHeight);//画一个矩形在x,y处画一个宽是200,高是300的矩形,
g.setColor(Color.BLACK);//颜色是黑的
LinkedList na = model.nodeArray;//LinkedList 类 List 接口的链接列表实现就是一个集合对象了,因为不知道SnakeModel具体是一个什么类这里就当作这个类能得到一个集合
Iterator it = na.iterator();//得到迭代器去迭代这个集合
while (it.hasNext()) {//开始用while迭代
Node n = (Node) it.next();//得到一个集合中元素.是一个Node....这里的Node不知道是什么对象..有待于研究
drawNode(g, n);//调用另外方法
}
g.setColor(Color.RED);//设置颜色是红的
Node n = model.food;//得到一个新node..看来Node这里应该是一个坐标..这里的坐标就是蛇吃的那个东西
drawNode(g, n);//画这个东西..
updateScore();//调用..
}
private void drawNode(Graphics g, Node n) {//这是一个画方的方法..动态改变方型的位置
g.fillRect(n.x * nodeWidth,
n.y * nodeHeight,
nodeWidth - 1,
nodeHeight - 1);
}
public void updateScore() {//这是更新标签的一个方法
String s = "Score: " + model.score;
labelScore.setText(s);
}
public void update(Observable o, Object arg) {//这个就是Observer监听类必须实现的方法..这里是去调用repaint()方法..repaint方法就是不断去改变画图版里面的内容的
repaint();
}
}
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JFrame;
public class InterFace extends JFrame {
/**
* WIDTH:宽
* HEIGHT:高
* SLEEPTIME:可以看作蛇运动的速度
* L = 1,R = 2, U = 3, D = 4 左右上下代码
*/
public static final int WIDTH = 800, HEIGHT = 600, SLEEPTIME = 200, L = 1,R = 2, U = 3, D = 4;
BufferedImage offersetImage= new BufferedImage(WIDTH, HEIGHT,BufferedImage.TYPE_3BYTE_BGR)
Rectangle rect = new Rectangle(20, 40, 15 * 50, 15 * 35);
Snake snake;
Node node;
public InterFace() {
//创建"蛇"对象
snake = new Snake(this);
//创建"食物"对象
createNode();
this.setBounds(100, 100, WIDTH, HEIGHT);
//添加键盘监听器
this.addKeyListener(new KeyAdapter() {
public void keyPressed(KeyEvent arg0) {
System.out.println(arg0.getKeyCode());
switch (arg0.getKeyCode()) {
//映射上下左右4个键位
case KeyEvent.VK_LEFT:
snake.dir = L;
break;
case KeyEvent.VK_RIGHT:
snake.dir = R;
break;
case KeyEvent.VK_UP:
snake.dir = U;
break;
case KeyEvent.VK_DOWN:
snake.dir = D;
}
}
});
this.setTitle("贪吃蛇 0.1 By : Easy");
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
this.setVisible(true);
//启动线程,开始执行
new Thread(new ThreadUpadte()).start();
}
public void paint(Graphics g) {
Graphics2D g2d = (Graphics2D) offersetImage.getGraphics();
g2d.setColor(Color.white);
g2d.fillRect(0, 0, WIDTH, HEIGHT);
g2d.setColor(Color.black);
g2d.drawRect(rect.x, rect.y, rect.width, rect.height);
//如果蛇碰撞(吃)到食物,则创建新食物
if (snake.hit(node)) {
createNode();
}
snake.draw(g2d);
node.draw(g2d);
g.drawImage(offersetImage, 0, 0, null);
}
class ThreadUpadte implements Runnable {
public void run() {
//无限重绘画面
while (true) {
try {
Thread.sleep(SLEEPTIME);
repaint(); //
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
/**
* 创建食物
*/
public void createNode() {
//随机食物的出现位置
int x = (int) (Math.random() * 650) + 50,y = (int) (Math.random() * 500) + 50;
Color color = Color.blue;
node = new Node(x, y, color);
}
public static void main(String args[]) {
new InterFace();
}
}
/**
* 节点类(包括食物和蛇的身躯组成节点)
*/
class Node {
int x, y, width = 15, height = 15;
Color color;
public Node(int x, int y, Color color) {
this(x, y);
this.color = color;
}
public Node(int x, int y) {
this.x = x;
this.y = y;
this.color = color.black;
}
public void draw(Graphics2D g2d) {
g2d.setColor(color);
g2d.drawRect(x, y, width, height);
}
public Rectangle getRect() {
return new Rectangle(x, y, width, height);
}
}
/**
* 蛇
*/
class Snake {
public ListNode nodes = new ArrayListNode();
InterFace interFace;
int dir=InterFace.R;
public Snake(InterFace interFace) {
this.interFace = interFace;
nodes.add(new Node(20 + 150, 40 + 150));
addNode();
}
/**
* 是否碰撞到食物
* @return true 是 false 否
*/
public boolean hit(Node node) {
//遍历整个蛇体是否与食物碰撞
for (int i = 0; i nodes.size(); i++) {
if (nodes.get(i).getRect().intersects(node.getRect())) {
addNode();
return true;
}
}
return false;
}
public void draw(Graphics2D g2d) {
for (int i = 0; i nodes.size(); i++) {
nodes.get(i).draw(g2d);
}
move();
}
public void move() {
nodes.remove((nodes.size() - 1));
addNode();
}
public synchronized void addNode() {
Node nodeTempNode = nodes.get(0);
//如果方向
switch (dir) {
case InterFace.L:
//判断是否会撞墙
if (nodeTempNode.x = 20) {
nodeTempNode = new Node(20 + 15 * 50, nodeTempNode.y);
}
nodes.add(0, new Node(nodeTempNode.x - nodeTempNode.width,
nodeTempNode.y));
break;
case InterFace.R:
//判断是否会撞墙
if (nodeTempNode.x = 20 + 15 * 50 - nodeTempNode.width) {
nodeTempNode = new Node(20 - nodeTempNode.width, nodeTempNode.y);
}
nodes.add(0, new Node(nodeTempNode.x + nodeTempNode.width,
nodeTempNode.y));
break;
case InterFace.U:
//判断是否会撞墙
if (nodeTempNode.y = 40) {
nodeTempNode = new Node(nodeTempNode.x, 40 + 15 * 35);
}
nodes.add(0, new Node(nodeTempNode.x, nodeTempNode.y - nodeTempNode.height));
break;
case InterFace.D:
//判断是否会撞墙
if (nodeTempNode.y = 40 + 15 * 35 - nodeTempNode.height) {
nodeTempNode = new Node(nodeTempNode.x,40 - nodeTempNode.height);
}
nodes.add(0, new Node(nodeTempNode.x, nodeTempNode.y + nodeTempNode.height));
break;
}
}
}