待解决疑问:
现在默认运行程序游戏直接开始,然后死亡后可以重新开始。有一个Menu类可以展示游戏欢迎界面,理想情况是:在欢迎界面按空格可以开始游戏,但是不知道如何实现。
程序入口
package Main;
public class Main extends GamePanel{
public static void main(String[] args) {
new GameFrame();
}
}
创建游戏窗口
package Main;
import javax.swing.JFrame;
import javax.swing.JTextField;
public class GameFrame extends JFrame{
public boolean menuclosed=false;
JTextField text;
GameFrame(){
this.setTitle("Greedy Snake");
this.setLocation(200,200);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setResizable(false);
this.add(new GamePanel());
this.pack();
this.setVisible(true);
}
}
在游戏窗口制作游戏内容
package Main;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.io.IOException;
import java.util.Random;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JPanel;
import javax.swing.Timer;
public class GamePanel extends JPanel implements ActionListener{
static final int SCREEN_WIDTH=500;
static final int SCREEN_HEIGHT=500;
static final int UNIT_SIZE=20;
static int GAME_GROUND=(SCREEN_WIDTH*SCREEN_HEIGHT)/UNIT_SIZE;
static int DELAY=140;
int x[]=new int[GAME_GROUND];
int y[]=new int [GAME_GROUND];
int snake=5;
public int applesEaten;
static int score;
int appleX;
int appleY;
char direction='R';
public boolean running=false;
Timer timer;
Random random;
Image imgbox;
GamePanel(){
System.out.println("GamePanel");
gameCreate();
}
private void gameCreate() {
x=new int[GAME_GROUND];
y=new int[GAME_GROUND];
snake=5;
applesEaten = 0;
score=0;
appleX = 0;
appleY = 0;
direction='R';
running=false;
this.setPreferredSize(new Dimension(SCREEN_WIDTH,SCREEN_HEIGHT));
this.setFocusable(true);
this.addKeyListener(new KAdapter());
this.setBackground(Color.black);
random=new Random();
gameStart();
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
draw(g);
}
public void draw(Graphics g) {
if(running) {
//Draw apple画苹果
g.setColor(new Color(6,31,191));
g.fillOval(appleX, appleY, UNIT_SIZE, UNIT_SIZE);
//Draw Snake画出蛇
for(int i=0;i<snake;i++) {
//Head of Snake画出蛇头
if(i==0) {
g.setColor(new Color(132,5,5));
g.fillRect(x[i], y[i], UNIT_SIZE, UNIT_SIZE);
}
//Body of Snake画出蛇身
else {
g.setColor(Color.gray);
g.fillRect(x[i], y[i], UNIT_SIZE, UNIT_SIZE);
}
}
scoreBoard(g);
}
else {
gameEnd(g);//如果游戏还在运行就画,不然启动游戏结束界面
}
}
public void gameStart() {
running=true;
createApple();
if(timer==null) {
timer=new Timer(DELAY,this);//重置timer,防止蛇死后重开再死再重开导致的速度越来越快
timer.start();
}
}
public void scoreBoard(Graphics g) {
g.setColor(Color.gray);
g.drawString("得分 "+score, 20, SCREEN_HEIGHT-g.getFont().getSize());
g.drawString("吞噬的星球 "+applesEaten, 200, SCREEN_HEIGHT-g.getFont().getSize());
g.drawString("坐标 "+x[0]+"|"+y[0], 300, SCREEN_HEIGHT-g.getFont().getSize());
}
public void createApple() {
//Set apple random location
appleX=random.nextInt((int)(SCREEN_WIDTH/UNIT_SIZE))*UNIT_SIZE;
appleY=random.nextInt((int)(SCREEN_HEIGHT/UNIT_SIZE))*UNIT_SIZE;
}
public void checkApple() {
//Make apple Edible
if((x[0]==appleX)&&(y[0]==appleY)){
snake++;
applesEaten++;
createApple();
}
}
public void move() {
for(int i=snake;i>0;i--) {
x[i]=x[i-1];
y[i]=y[i-1];
}
switch(direction) {
case 'U':
y[0]=y[0]-UNIT_SIZE;
break;
case 'D':
y[0]=y[0]+UNIT_SIZE;
break;
case 'L':
x[0]=x[0]-UNIT_SIZE;
break;
case 'R':
x[0]=x[0]+UNIT_SIZE;
break;
}
}
public void checkCollision() {
for(int i=snake;i>0;i--) {
//Game end when head touching body
if((x[0]==x[i])&&(y[0]==y[i])){
running=false;
}
//Game end when head spanned the game field
if((x[0]<0)||(x[0]>SCREEN_WIDTH)||(y[0]<0)||(y[0]>SCREEN_HEIGHT)) {
running=false;
}
}
}
public void gameEnd(Graphics g) {
this.setBackground(Color.darkGray);
String speaker=null;
if(applesEaten==0) {speaker=text[0];}
if(applesEaten==2) {speaker=text[1];}
if(applesEaten==5) {speaker=text[2];}
if(applesEaten==12) {speaker=text[3];}
if(applesEaten>200) {speaker=text[4];}
else {speaker=text[7];}
g.setColor(Color.lightGray);
//"Greedy Snake"
g.setFont(new Font("Impact",Font.PLAIN,50));
g.drawString("Greedy Snake",SCREEN_WIDTH/4, g.getFont().getSize());
//"Score - "
g.setFont(new Font(null,Font.BOLD,25));
g.drawString("Score - "+score,SCREEN_WIDTH/6, 100);
//Other text
g.setFont(new Font(null,Font.ROMAN_BASELINE,15));
g.drawString("你吞噬了"+applesEaten+"个星球. "+speaker,SCREEN_WIDTH/6, 145);
g.drawString("R-重新开始", SCREEN_WIDTH/6, 180);
g.drawString("Esc-退出游戏", SCREEN_WIDTH/6,205);
//Prevent timer
if(timer!=null) {
timer.stop();
timer=null;
}
}
@Override
public void actionPerformed(ActionEvent e) {
if(running) {move();checkApple();checkCollision();}
repaint();
}
public class KAdapter extends KeyAdapter{
@Override
public void keyPressed(KeyEvent e) {
switch(e.getKeyCode()) {
case KeyEvent.VK_LEFT:
if(direction!='R') {
direction='L';
}
break;
case KeyEvent.VK_RIGHT:
if(direction!='L') {
direction='R';
}
break;
case KeyEvent.VK_UP:
if(direction!='D') {
direction='U';
}
break;
case KeyEvent.VK_DOWN:
if(direction!='U') {
direction='D';
}
break;
case KeyEvent.VK_R:
if(!running) {
gameCreate();
}
case KeyEvent.VK_ESCAPE:
if(!running) {
System.exit(0);
}
}
}
}
//结算界面台词
final public String []text= {
"(T_T)",
"我们的地球和火星消失了.",
"这些加起来或许比得上木星.",
"相当于整个太阳系!",
"你和黑洞有血缘关系?",
"你啃腹自尽了.",
"真是可笑至极...",
"[返航中]"};
}
待解决,下面是游戏欢迎界面Menu,在GameFrame游戏窗口可以添加显示,跟着游戏界面指示“按space开始游戏”,GameFrame没法加载GamePanel游戏制作界面,我不知道为什么没法达成没法从欢迎界面进入游玩界面的效果。
package Main;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class Menu extends JPanel implements ActionListener{
static final int SCREEN_WIDTH=500;
static final int SCREEN_HEIGHT=500;
public JLabel title;
public JLabel text1,text2;
public boolean menuenable=true;//用来表示欢迎页面是否展示,默认展示
public int operator;
Menu(){
if(menuenable) {
System.out.println("Menu");
this.setPreferredSize(new Dimension(SCREEN_WIDTH,SCREEN_HEIGHT));
this.setBackground(Color.black);
this.addKeyListener(new KAdapter());
this.setFocusable(true);
title=new JLabel("Greddy Snake");
title.setFont(new Font("Impact",Font.BOLD,50));
title.setForeground(Color.white);
this.add(title);
}
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
draw(g);
}
public void draw(Graphics g) {//画游戏提示语和logo
if(menuenable) {
g.setColor(Color.gray);
g.setFont(new Font(null,Font.ROMAN_BASELINE,20));
g.drawString("Space - start game",20,SCREEN_HEIGHT-g.getFont().getSize());
Toolkit tool=this.getToolkit();
Image logoimg=tool.getImage("LOGO.png");
g.drawImage(logoimg,90,90,(logoimg.getWidth(this))*3,(logoimg.getHeight(this))*3,this);
}
}
@Override
public void actionPerformed(ActionEvent e) {
}
public class KAdapter extends KeyAdapter{
@Override
//按空格开始游戏,按K更改难度。(暂时不配置K)
public void keyPressed(KeyEvent k) {
if(menuenable) {
switch(k.getKeyCode()) {
case KeyEvent.VK_SPACE:
System.out.println("spcace");
menuenable=false;
break;
case KeyEvent.VK_F:
System.out.println("f");
menuenable=false;
break;
}
}
}
}
}