public
網(wǎng)站建設(shè)哪家好,找創(chuàng)新互聯(lián)!專注于網(wǎng)頁設(shè)計、網(wǎng)站建設(shè)、微信開發(fā)、微信小程序、集團企業(yè)網(wǎng)站建設(shè)等服務(wù)項目。為回饋新老客戶創(chuàng)新互聯(lián)還提供了衡陽免費建站歡迎大家使用!
class
Snake
implements
Data//蛇類實現(xiàn)了data接口
{
public
Snake()
{
array.add(new
Point(10,
10));//
array.add(new
Point(10,
11));//
array.add(new
Point(10,
12));//
array.add(new
Point(10,
13));//
array.add(new
Point(10,
14));//這五句話是構(gòu)造一個蛇,這條蛇由五個坐標(biāo)點連成
currentFlag
=UPFLAG
;//當(dāng)前的運動方向設(shè)為向上
lifeFlag
=
true;//當(dāng)前蛇的生命設(shè)為活著
}
public
void
move()//蛇的運動函數(shù)
{
tair
=
(Point)array.get(array.size()
-
1);//得到蛇的尾巴
int
len
=
array.size()
-
2;
for(int
i
=
len;
i
=
0;
i--)//這個for循環(huán)把蛇的每一個點都坐標(biāo)偏移即運動了
{
Point
leftPoint
=
(Point)array.get(i);
Point
rightPoint
=
(Point)array.get(i
+
1);
rightPoint.x
=
leftPoint.x;
rightPoint.y
=
leftPoint.y;//每一個右邊的點等于其左邊的點,像蛇那樣的一縮一張的運動
}
}
public
void
moveHeadLeft()//把蛇的頭部轉(zhuǎn)向左邊
{
if(currentFlag
==
RIGHTFLAG
||
currentFlag
==
LEFTFLAG)//如果運動方向設(shè)為向左或向右則不執(zhí)行
{
return;
}
move();
Point
point
=
(Point)(array.get(0));
//得到蛇頭部
point.x
=
point.x
-
1;//蛇頭部橫坐標(biāo)減一,縱坐標(biāo)不變
point.y
=
point.y;
if(point.x
LEFT)//如果蛇頭部不能再左,就不執(zhí)行
{
lifeFlag
=
false;
}
currentFlag
=
LEFTFLAG;//將蛇運動方向改為左
}
J2ME貪吃蛇源代碼——200行左右,包含詳細(xì)注釋 package snake;import javax.microedition.midlet.*;
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{
/**存儲貪吃蛇節(jié)點坐標(biāo),其中第二維下標(biāo)為0的代表x坐標(biāo),第二維下標(biāo)是1的代表y坐標(biāo)*/
int[][] snake = new int[200][2];
/**已經(jīng)使用的節(jié)點數(shù)量*/
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;/**游戲區(qū)域?qū)挾?/
int width;
/**游戲區(qū)域高度*/
int height;/**蛇身單元寬度*/
private final byte SNAKEWIDTH = 4;/**是否處于暫停狀態(tài),true代表暫停*/
boolean isPaused = false;
/**是否處于運行狀態(tài),true代表運行*/
boolean isRun = true;/**時間間隔*/
private final int SLEEP_TIME = 300;
/**食物的X坐標(biāo)*/
int foodX;
/**食物的Y坐標(biāo)*/
int foodY;
/**食物的閃爍控制*/
boolean b = true;
/**Random對象*/
Random random = new Random();
public SnakeCanvas() {
//初始化
init();
width = this.getWidth();
height = this.getHeight();
//啟動線程
new Thread(this).start();
}/**
* 初始化開始數(shù)據(jù)
*/
private void init(){
//初始化節(jié)點數(shù)量
snakeNum = 7;
//初始化節(jié)點數(shù)據(jù)
for(int i = 0;i snakeNum;i++){
snake[i][0] = 100 - SNAKEWIDTH * i;
snake[i][1] = 40;
}
//初始化移動方向
direction = DIRECTION_RIGHT;
//初始化食物坐標(biāo)
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();
}
}
/**
* 產(chǎn)生食物
* 說明:食物的坐標(biāo)必須位于屏幕內(nèi),且不能和蛇身重合
*/
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;
}
}
}
/**
* 判斷游戲是否結(jié)束
* 結(jié)束條件:
* 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:
//暫停和繼續(xù)
isPaused = !isPaused;
break;
}
}/**
* 線程方法
* 使用精確延時
*/
public void run(){
try{
while (isRun) {
//開始時間
long start = System.currentTimeMillis();
if(!isPaused){
//吃食物
eatFood();
//移動
move(direction);
//結(jié)束游戲
if(isGameOver()){
break;
}
//控制閃爍
b = !b;
}
//重新繪制
repaint();
long end = System.currentTimeMillis();
//延時
if(end - start SLEEP_TIME){
Thread.sleep(SLEEP_TIME - (end - start));
}
}
}catch(Exception e){}
}
}
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() {
//創(chuàng)建"蛇"對象
snake = new Snake(this);
//創(chuàng)建"食物"對象
createNode();
this.setBounds(100, 100, WIDTH, HEIGHT);
//添加鍵盤監(jiān)聽器
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);
//啟動線程,開始執(zhí)行
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);
//如果蛇碰撞(吃)到食物,則創(chuàng)建新食物
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();
}
}
}
}
/**
* 創(chuàng)建食物
*/
public void createNode() {
//隨機食物的出現(xiàn)位置
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();
}
}
/**
* 節(jié)點類(包括食物和蛇的身軀組成節(jié)點)
*/
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;
}
}
}
/**
* MVC模式中得Viewer,只負(fù)責(zé)對數(shù)據(jù)的顯示,而不用理會游戲的控制邏輯
*/
class SnakeView implements Observer {
SnakeControl control = null; //實例話一個SnakeControl對象是control ..SnakeControl在jdk中不存在可能是第3方的或者是自己編寫的一個類吧
SnakeModel model = null;//如上
JFrame mainFrame; //創(chuàng)建一個面板類jframe
Canvas paintCanvas;
/**
*Canvas 組件表示屏幕上一個空白矩形區(qū)域,應(yīng)用程序可以在該區(qū)域內(nèi)繪圖,或者可以從該區(qū)域捕獲用戶的輸入事件。
*應(yīng)用程序必須為 Canvas 類創(chuàng)建子類,以獲得有用的功能(如創(chuàng)建自定義組件)。必須重寫 paint 方法,以便在 canvas 上執(zhí)行自定義圖形。
*/
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");//創(chuàng)建jframe 標(biāo)題是GreedSnake
Container cp = mainFrame.getContentPane(); //得到j(luò)fram的容器
labelScore = new JLabel("Score:"); //創(chuàng)建jlabel 標(biāo)簽內(nèi)容是"Score:"
cp.add(labelScore, BorderLayout.NORTH);/將jlabel添加到j(luò)fram的容器中去
paintCanvas = new Canvas(); //創(chuàng)建新繪圖區(qū)
paintCanvas.setSize(canvasWidth + 1, canvasHeight + 1); //設(shè)置繪圖區(qū)大小
paintCanvas.addKeyListener(control);//添加鍵盤監(jiān)聽器control
cp.add(paintCanvas, BorderLayout.CENTER);//將繪圖區(qū)添加到j(luò)fram容器中去.布局是BorderLayout的CENTER位置.就是東西南北中的中間
JPanel panelButtom = new JPanel();//創(chuàng)建一個panel
panelButtom.setLayout(new BorderLayout());//設(shè)置布局是BorderLayout
JLabel labelHelp;//標(biāo)簽的創(chuàng)建和添加開始了.......new了3遍就是實例化了3個都加到了panle的中間 ,標(biāo)簽的內(nèi)容都是""中間的
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添加到j(luò)frame的容器里面去
mainFrame.addKeyListener(control);//為jframe添加鍵盤監(jiān)聽器
mainFrame.pack();//調(diào)整此窗口的大小,以適合其子組件的首選大小和布局。如果該窗口和/或其所有者仍不可顯示,則兩者在計算首選大小之前變得可顯示。在計算首選大小之后,將會驗證該 Window。
mainFrame.setResizable(false);//設(shè)置此 frame 是否可由用戶調(diào)整大小。false就是不能
mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//點擊又上角的就是關(guān)閉
mainFrame.setVisible(true);//設(shè)置jfram為能看到
}
void repaint() {
Graphics g = paintCanvas.getGraphics();//Graphics詳細(xì)看jdk文檔..我就知道是一個所有圖形上下文的抽象基類..這里應(yīng)該是那個畫圖面板
g.setColor(Color.WHITE);//設(shè)置這個顏色
g.fillRect(0, 0, canvasWidth, canvasHeight);//畫一個矩形在x,y處畫一個寬是200,高是300的矩形,
g.setColor(Color.BLACK);//顏色是黑的
LinkedList na = model.nodeArray;//LinkedList 類 List 接口的鏈接列表實現(xiàn)就是一個集合對象了,因為不知道SnakeModel具體是一個什么類這里就當(dāng)作這個類能得到一個集合
Iterator it = na.iterator();//得到迭代器去迭代這個集合
while (it.hasNext()) {//開始用while迭代
Node n = (Node) it.next();//得到一個集合中元素.是一個Node....這里的Node不知道是什么對象..有待于研究
drawNode(g, n);//調(diào)用另外方法
}
g.setColor(Color.RED);//設(shè)置顏色是紅的
Node n = model.food;//得到一個新node..看來Node這里應(yīng)該是一個坐標(biāo)..這里的坐標(biāo)就是蛇吃的那個東西
drawNode(g, n);//畫這個東西..
updateScore();//調(diào)用..
}
private void drawNode(Graphics g, Node n) {//這是一個畫方的方法..動態(tài)改變方型的位置
g.fillRect(n.x * nodeWidth,
n.y * nodeHeight,
nodeWidth - 1,
nodeHeight - 1);
}
public void updateScore() {//這是更新標(biāo)簽的一個方法
String s = "Score: " + model.score;
labelScore.setText(s);
}
public void update(Observable o, Object arg) {//這個就是Observer監(jiān)聽類必須實現(xiàn)的方法..這里是去調(diào)用repaint()方法..repaint方法就是不斷去改變畫圖版里面的內(nèi)容的
repaint();
}
}