目錄
實驗準備
1.實驗參考
2.實驗總體思路
一. 界面設計
二. 蛇的初始化
三. 鍵盤監聽
四. 隨機生成食物
五. 判斷蛇吃食物
六. 蛇的移動和防止超出邊界
七. 蛇的死亡
八. 定時器
成品展示
實驗準備
1.實驗參考
實驗參考的是B站UP主麥數編程的教程,鏈接:貪吃蛇:1小時Java開發貪吃蛇游戲 [編號:J301]_嗶哩嗶哩_bilibili,同時在他的基礎上對貪吃蛇加上一些更改和限定,
2.實驗總體思路

一. 界面設計
我使用的貪吃蛇是在Snake.java的主方法中創建了一個JFrame物件,然后在新的檔案 MyPanel.java創建了一個MyPanel類繼承JPanel,在JPanel中繪制貪吃蛇游戲,最后添加進JFrame物件中,
protected void paintComponent(Graphics g) {
super.paintComponent(g);
//自動填充背景顏色
this.setBackground(new Color(246, 241, 200));
//畫頭部圖片
//paintIcon 四個引數:this 指的是當前面板 g:知道是畫筆 x,y 指的是對應坐標
//調畫筆顏色
g.setColor(new Color(0xE7DFDF));
//畫一個矩形
g.fillRect(10, 70, 760, 685);
//畫蛇頭
if ("R".equals(direction)) {
Images.rightImg.paintIcon(this, g, snakeX[0], snakeY[0]);
} else if ("L".equals(direction)) {
Images.leftImg.paintIcon(this, g, snakeX[0], snakeY[0]);
} else if ("U".equals(direction)) {
Images.upImg.paintIcon(this, g, snakeX[0], snakeY[0]);
} else if ("D".equals(direction)) {
Images.downImg.paintIcon(this, g, snakeX[0], snakeY[0]);
}
//身子
for (int i = 1; i < length; i++) {
Images.bodyImg.paintIcon(this, g, snakeX[i], snakeY[i]);
}
//游戲提示語
if (isStart == false) {
//畫一個文字
g.setColor(new Color(0xFF7373));
//字體 字號 大小
g.setFont(new Font("微軟雅黑", Font.BOLD, 40));
//文字內容 出現的位置
g.drawString("點擊空格開始/暫停游戲", 200, 330);
}
Images.foodImg.paintIcon(this, g, foodX, foodY);
g.setColor(new Color(255, 76, 76));
g.setFont(new Font("微軟雅黑", Font.BOLD, 40));
g.drawString("積分" + ":" + score, 600, 40);
二. 蛇的初始化
我使用的是陣列來進行對蛇的初始化和存盤,每吃到一個食物便對蛇身加長一次,也就是在陣列當中存入一次資料,并將其加在蛇身上,
//蛇的長度:
int length;
public void init() {
//初始化蛇的長度:
length = 3;
//圖片大小為25x25
//初始化蛇頭軸坐標:
snakeX[0] = 175;
snakeY[0] = 175;
//初始化第一節身子坐標:
snakeX[1] = 150;
snakeY[1] = 175;
//初始化第二節身子坐標:
snakeX[2] = 125;
snakeY[2] = 175;
//初始化蛇頭的方向:
direction = "R";
//食物初始的坐標
foodX = 300;
foodY = 200;
//積分
score = 0;
}
三. 鍵盤監聽
要對蛇進行上下左右的控制就需要我們隊蛇進行鍵盤的監聽,我們可以通過KeyListener來對鍵盤進行監聽 相關方法:KeyListener_java_5666666的博客-CSDN博客_keylistener
同時,我加入了按空格來對游戲的開始、暫停以及重新開始,同時還有一個限定條件,比如:當蛇在向上移動的時候,我們按鍵盤的下和上蛇應該是不會有任何反應的,否則便會出現蛇直接回頭將自己吃掉的情況,
this.addKeyListener(new KeyAdapter() {
@Override
public void keyPressed(KeyEvent e) {//監聽鍵盤按鍵的按下操作
super.keyPressed(e);
int keyCode = e.getKeyCode();
//System.out.println(keyCode); 32
if (keyCode == KeyEvent.VK_SPACE) {//監聽空格
if (isDie) {
init();
isDie = false;
} else {
isStart = !isStart;
}
repaint();//重繪游戲
}
//監聽上下左右
switch (keyCode) {
case KeyEvent.VK_UP:
if (!direction.equals("D")){
direction = "U";
}
break;
case KeyEvent.VK_DOWN:
if (!direction.equals("U")){
direction = "D";
}
break;
case KeyEvent.VK_RIGHT:
if (!direction.equals("L")){
direction = "R";
}
break;
case KeyEvent.VK_LEFT:
if (!direction.equals("R")){
direction = "L";
}
break;
}
}
}
我的代碼當中,是定義了一個direction來存盤蛇的行動方向,同時也通過其中存放的字母來判斷蛇可以向哪個方向更改,
四. 隨機生成食物
為了防止食物的生成會和蛇的位置重疊,需要在生成的坐標后面進行判斷,遍歷蛇的所以位置,一旦相同,重新生成一個,
private void setMinFood() {
Boolean setFood;
do {
setFood = true;
foodx = 25 + 25 * rand.nextInt(34);
foody = 110 + 25 * rand.nextInt(24);
p = first;
// 防止生成的食物在蛇身上
while (p != null) {
if (p.getX() == foodx && p.getY() == foody) {
setFood = false;
break;
}
p = p.next;
}
if ((foodx == bigFoodx && foody == bigFoody)
|| (foodx == bigFoodx -25 && foody == bigFoody)
|| (foodx == bigFoodx && foody == bigFoody - 25)
|| (foodx == bigFoodx -25 && foody == bigFoody - 25)) {
setFood = false;
}
} while (!setFood);
}
五. 判斷蛇吃食物
每次出現的食物都會有一個屬于它的坐標,我們只需要判斷蛇頭的坐標和食物的坐標是否重合便可以判斷蛇是否吃到了食物,
if (snakeX[0] == foodX && snakeY[0] == foodY) {
//長度加+
length++;
//隨機生成坐標
foodX = ((int) (Math.random() * 30) + 1) * 25;//[25,750]
foodY = (new Random().nextInt(26) + 4) * 25;//[100,750]
score += 10;
}
六. 蛇的移動和防止超出邊界
通過一開始定義的蛇的陣列來實作蛇的移動,我們只需要將蛇的每一節放置在界面的坐標當中,然后通過判定方向來對蛇身的每一節進行坐標的加減即可,同時,如果蛇頭碰到了邊界坐標,那么我們就會判定蛇死亡,
if (isStart && isDie == false) {
//身子
for (int i = length - 1; i > 0; i--) {
snakeX[i] = snakeX[i - 1];
snakeY[i] = snakeY[i - 1];
}
if ("R".equals(direction)) {
snakeX[0] += 25;
} else if ("U".equals(direction)) {
snakeY[0] -= 25;
} else if ("D".equals(direction)) {
snakeY[0] += 25;
} else if ("L".equals(direction)) {
snakeX[0] -= 25;
}
//防止蛇超出邊界:
if (snakeX[0] > 750) {
isDie = true;
} else if (snakeY[0] < 100) {
isDie = true;
} else if (snakeX[0] < 25) {
isDie = true;
} else if (snakeY[0] > 725) {
isDie = true;
}
七. 蛇的死亡
除了上面的蛇頭碰到邊界我們判定蛇死亡之外,還有如果蛇碰到了自己的身體我們也會判定蛇死亡,同樣的我們只需要判定蛇頭的坐標和蛇身的坐標是否在同一時間處于同一個坐標,如果是的話,那么我們便可以判斷蛇死亡,同時進行畫面的重繪,
//死亡判斷
for (int i = 1; i < length; i++) {
if (snakeX[i] == snakeX[0] && snakeY[i] == snakeY[0]) {
isDie = true;
}
}
repaint();
八. 定時器
最后我們需要加入一個定時器來實作畫面的移動,否則我們的貪吃蛇將不能移動,
timer = new Timer(100, new ActionListener() {}
timer.start(); //定時器啟動
成品展示

小蛇死亡:

轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/388021.html
標籤:其他
上一篇:C語言----掃雷游戲
下一篇:郭依婷—大學生的創業故事
