学习目标:
学习开发一款类似贪吃蛇的小游戏,虽然其实一样,但我把他叫做贪吃嘴,嘿嘿,食物总是使人开心的,想要有一个速度之间的变化,还有可以自主选择图形的界面,不过现在还没学到,先展示一些写好的吧
学习内容:
先是创建了Mtanchi这个类,在这里来创建一个窗口,先做一个游戏的界面,游戏开始界面暂时还没弄好
建立Mpanel类的时候先是制作出一个白色的窗口,再在窗口的上面放置一个吃豆豆的标题,这个图片可以自己去PPT里面制作一个自己喜欢的,然后设置一个游戏区。
游戏区先放置一个静态的身体,设置一下贪吃嘴开始的方向,贪吃嘴出现的区域,并且做一下不同方向贪吃嘴显示的头。
做一下用按键显示,那么就需要用一下按键的监听,我设计的是当按键按下时出现提示,按下空格出现游戏暂停,游戏结束时再按下按钮就可以从新开始开始游戏。
下面就是把静态的变成动态的,我们可以想象一下,当嘴向前移动时,他的身体第一节应该到达头的位置,第二节身体到达第一节身体的位置。用一个循环来做就可以了。
再下面就是实现转向,监听一下按钮的上下左右键,实现头方向的改变。
下一步添加食物,我们先调用一下随机函数,因为总不能每一次的食物都是由我们手动输入的吧。然后确定一下食物出现的区域,不能大于游戏区域,并且出现的位置不能与贪吃嘴相重合。
下一步当然就是你操作他去吃掉食物,然而食物被吃掉会出现什么变化,怎么样食物算被吃掉呢。当头的位置与食物相重合的时候食物就被吃掉,吃掉一个食物身体长一节。
游戏结束的条件,嘴撞到身体和嘴撞到游戏边界时游戏结束。
下一步添加游戏的分数和长度
首先说明有借鉴哈,借鉴太多我也记不得了。
package tanchi;
import javax.swing.JFrame;
public class Mtanchi {
public static void main(String[] args){
JFrame frame=new JFrame();//创建一个窗口,类型和名字叫做Jframe
frame.setBounds(10,10,900,720);//窗口放置位置和窗口的大小
frame.setResizable(false);//不能拖动改变大小
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//点击x的时候关闭窗口
frame.add(new MPanel());//调用MPanel,一直向下面执行就会执行到背景
frame.setVisible(true);//窗口展现出来
}
}
package tanchi;
import javax.swing.*;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.Random;
import javax.swing.Timer;
public class MPanel extends JPanel implements KeyListener,ActionListener//继承与JPanel implements KeyListener也可以处理键盘
{
ImageIcon title=new ImageIcon("F:\\贪吃蛇\\图片\\title.jpg");//引入图片
ImageIcon body=new ImageIcon("F:\\贪吃蛇\\图片\\body.png");
ImageIcon up=new ImageIcon("F:\\贪吃蛇\\图片\\up.png");
ImageIcon down=new ImageIcon("F:\\贪吃蛇\\图片\\down.png");
ImageIcon left=new ImageIcon("F:\\贪吃蛇\\图片\\left.png");
ImageIcon right=new ImageIcon("F:\\贪吃蛇\\图片\\right.png");
ImageIcon food=new ImageIcon("F:\\贪吃蛇\\图片\\food.png");
int len=3;//默认身体开始长度
int[] tanchizuix=new int [750];//存储贪吃嘴的x坐标
int[] tanchizuiy=new int [750];//存储贪吃嘴的x坐标
String fx="R";//定义方向:R,L,U,D
boolean isStarted=false;//开始是关闭状态
Timer timer=new Timer(500, this);//100毫秒到点,找自己,ActionListener
int foodx;
int foody;
Random rand=new Random();//引入随机函数
boolean isFail=false;//死亡判断
int score;
JButton startButton,stopButton,quitButton;
public MPanel(){//构造函数
initTanchizui();//调用一下开始时的状态
this.setFocusable(true);//可不可以获取焦点
this.addKeyListener(this);
timer.start();//时钟启动
/*startButton=new JButton("开始");
stopButton = new JButton("暂停");
quitButton = new JButton("退出");
this.add(startButton);
this.add(stopButton);
this.add(quitButton);
startButton.addActionListener(this);
stopButton.addActionListener(this);
quitButton.addActionListener(this);
*/
}
//初始化
public void initTanchizui(){
len=1;
tanchizuix[0]=25+25*rand.nextInt(34);;
tanchizuiy[0]=75+25*rand.nextInt(24);
//tanchizuix[0]=100;
//tanchizuiy[0]=100;
/*tanchizuix[1]=75;
tanchizuiy[1]=100;
tanchizuix[2]=50;
tanchizuiy[2]=100;//初始化贪吃嘴的身体
*/
foodx=25+25*rand.nextInt(34);//随机出现位置
foody=75+25*rand.nextInt(24);
fx="R";//死掉后从新开始是头向右
score=0;
}
public void paintComponent(Graphics g){//定义了一个方法画出键,Graphics画笔
super.paintComponent(g);//调用父类
this.setBackground(Color.WHITE);//设置背景色
title.paintIcon(this,g,23,11);//图片放置位置
g.fillRect(25,75,825,600);//游戏区放置区
//说明一下方向不同头也不同
if(fx=="R"){
right.paintIcon(this,g,tanchizuix[0],tanchizuiy[0]);//显示头
}
else if(fx=="L"){
left.paintIcon(this,g,tanchizuix[0],tanchizuiy[0]);//显示头
}
else if(fx=="D"){
down.paintIcon(this,g,tanchizuix[0],tanchizuiy[0]);//显示头
}
else if(fx=="U"){
up.paintIcon(this,g,tanchizuix[0],tanchizuiy[0]);//显示头
}
for(int i=1;i<len;i++){//身体从1开始
body.paintIcon(this,g,tanchizuix[i],tanchizuiy[i]);
}
//画食物
food.paintIcon(this,g,foodx,foody);//食物出现
//画成绩
g.setColor(Color.WHITE);
g.setFont(new Font("宋体", Font.BOLD, 22));//设置字体
g.drawString("长度"+len, 750, 35);//设置出现的位置和内容
g.drawString("分数"+score, 750, 65);
if(isStarted==false) {
g.setColor(Color.ORANGE);//设置颜色
g.setFont(new Font("华文行楷", Font.BOLD, 30));//设置字体
g.drawString("按下空格开始游戏", 300, 300);//设置出现的位置和内容
}
//失败提示
if(isFail){
g.setColor(Color.ORANGE);//设置颜色
g.setFont(new Font("华文行楷", Font.BOLD, 30));//设置字体
g.drawString("游戏失败,按下空格从新开始", 250, 300);//设置出现的位置和内容
}
//right.paintIcon(this,g,100,100);//静态身体的放置
//body.paintIcon(this,g,75,100);
//body.paintIcon(this,g,50,100);
}
@Override
public void keyTyped(KeyEvent e) {//当键盘敲击了
}
@Override
public void keyPressed(KeyEvent e) {//敲到底了 KeyEvent 敲击了那个键
int keyCode=e.getKeyCode();
if(keyCode==KeyEvent.VK_SPACE) {//如果是空格键
if(isFail){
isFail=false;
initTanchizui();//从新初始化游戏
}
else{
isStarted = !isStarted;//暂停游戏
}
repaint();//再画一次
}//改变头的方向
else if(keyCode==KeyEvent.VK_LEFT){
fx="L";
}
else if(keyCode==KeyEvent.VK_RIGHT){
fx="R";
}
else if(keyCode==KeyEvent.VK_UP){
fx="U";
}
else if(keyCode==KeyEvent.VK_DOWN){
fx="D";
}
}
@Override
public void keyReleased(KeyEvent e) {//键盘抬起来了
}
@Override
public void actionPerformed(ActionEvent e) {//ActionListener 时钟到了调用这个方法
//如果游戏处于开始状态并且游戏并没有结束
if(isStarted&&isFail==false) {
for (int i = len - 1; i > 0; i--) {//后面一个身体移到前一个身体的坐标上
tanchizuix[i] = tanchizuix[i - 1];
tanchizuiy[i] = tanchizuiy[i - 1];
}//
if (fx == "R") {
tanchizuix[0] = tanchizuix[0] + 25;
if (tanchizuix[0] > 825) isFail=true;// 现在变成到边界后死亡tanchizuix[0] = 25;//当头大于边界,重新开始
} else if (fx == "L") {
tanchizuix[0] = tanchizuix[0] - 25;
if (tanchizuix[0] < 25) isFail=true;//tanchizuix[0] = 830;//当头大于边界,重新开始
}
if (fx == "U") {
tanchizuiy[0] = tanchizuiy[0] - 25;
if (tanchizuiy[0] < 75) isFail=true;// tanchizuiy[0] = 650;//当头大于边界,重新开始
}
if (fx == "D") {
tanchizuiy[0] = tanchizuiy[0] + 25;
if (tanchizuiy[0] > 650) isFail=true;//tanchizuiy[0] = 75;//当头大于边界,重新开始
}
//如果小蛇头和食物坐标重合
if (tanchizuix[0] == foodx && tanchizuiy[0] == foody) {
len++;
score=score+10;
foodx=25+25*rand.nextInt(33);//随机出现位置
foody=75+25*rand.nextInt(24);
}
/*if (score==100) {
len++;
score=score+10;
foodx=25+25*rand.nextInt(33);//随机出现位置
foody=75+25*rand.nextInt(24);
}
*/
//结束判断
for(int i=1;i<len;i++){
if(tanchizuix[0] == tanchizuix[i] && tanchizuiy[0] ==tanchizuiy[i])
{
isFail=true;
}
/*if((tanchizuix[0] > 830)||(tanchizuix[0] < 25)) {
isFail=true;
}
if((tanchizuiy[0] < 75)||(tanchizuiy[0] > 650)) {
isFail=true;
}*/
}
repaint();//重新在画一次
}
timer.start();
}
}
学习时间:
2021-12-9
2021-12-10
学习产出:
这里先说一下还未完成的部分吧
首先这个有一个问题就是,嘴到边界的最后一个其实还没有死,本来如果你碰到边界才死,但是我这个就是你要跳出边界才死,去学习一下,不过我暂时事觉得当嘴到达边界最后一个并且嘴的方向没有变的时候那么就死了,嘿嘿,我感觉是这样。
还有就是还需要设计一个开始界面来连接这个游戏界面,我这个联系还不会,哎呀,头疼。
还有就是这个不好看。
不过我的头是随机出现的哟,就是方向随机这一点还未解决,我感觉需要好好想想。