如何在两个类之间传递状态

imonkeyi 2019-01-11 01:42:43
我在写一个贪吃蛇的小游戏,我写了三个类Win是框架窗口,Gwin是游戏区域panel有一个内部Thread类且实现了键盘监听器,里面放按钮和绘制图形,Snake具有蛇的一些特征如移动和吃食物。
关于蛇的移动我是这样想的,先按照将一个数组的值向前移动一位的方法设置蛇身的位置,再根据蛇的方向状态设置蛇头是左右或者是上下移动。
因为键盘监听器是再Gwin中实现的,所以我一开始在Gwin中设置了一个枚举来保存四种不同方向的状态,在keyPressed()方法中改变一个全局枚举变量的值,然后再把把这个值传递给Snake类中的全局枚举变量,再Snake类中的snakeMove方法中按照上诉方法移动蛇的位置,但是枚举类型里面的值是公共静态最终变量,值传递不能改变实参的值,后来我又试了字符串,还是不行。
说了这么多,主要问题如标题所述,各位大佬有没有好一点的解决方案?
[size=14px][/size]
package Mysnake2;

import javax.swing.ImageIcon;
import javax.swing.JFrame;
import java.awt.Toolkit;
import java.awt.Dimension;
import java.awt.Image;
import java.awt.Insets;
import java.util.Random;

public class Win2 extends JFrame{ //游戏窗口

//窗口大小
public static int width=800,height=500;
private Toolkit toolkit;
private Dimension screensize;
private String title;
private Image image;
private Gwin2 gwin2;
private Insets insets;
private Dimension jframesize;

public Win2()
{
this.setSize(width+6, height+35);
//窗口居中
toolkit=Toolkit.getDefaultToolkit();
screensize=toolkit.getScreenSize();
this.setLocation((screensize.width-width)/2, (screensize.height-height)/2);
//设置图标和标题
image=new ImageIcon(Win2.class.getResource("image/snake.jpg")).getImage();
this.setIconImage(image);
title="贪吃蛇";
this.setTitle(title);
this.setResizable(false);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//添加panel组件
gwin2=new Gwin2();
this.add(gwin2);
//设置布局管理器为空,否则在游戏区域中设置的坐标无效
this.setLayout(null);
//获取JFrame的内容面板和边框大小,要设置在窗口可见之前
this.setVisible(true);
insets=this.getInsets();
jframesize=this.getContentPane().getSize();
System.out.println("窗口边框上:"+insets.top);
System.out.println("窗口边框下:"+insets.bottom);
System.out.println("窗口边框左:"+insets.left);
System.out.println("窗口边框右:"+insets.right);
System.out.println("内容面板宽度:"+jframesize.width);
System.out.println("窗口边框高度:"+jframesize.height);
Random rand=new Random();
System.out.println(rand.nextInt(20));
System.out.println(Math.random());
System.out.println(Gwin2.direction);
}
public static void main(String[] arg)
{
new Win2();
}
}

package Mysnake2;

import java.awt.Color;
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.ArrayList;
//import java.util.Random;
import javax.swing.JPanel;
import javax.swing.JButton;
//import Mysnake2.Snake1.Direction;
/*
* 比较字符串是否相等
*
*
*
*/
public class Gwin2 extends JPanel implements ActionListener,KeyListener{//游戏区域

//定义区域大小和坐标,格子大小
private int width,height;
public static final int size=20;
private JButton but_start;
private JButton but_stop;
private Thread thread;
private Mythread mythread;
private Snake1 snake1;
ArrayList<Node1> snake;
private boolean flag;
//public static Direction direction;
public static String direction="right"; //方向
//private String direction;
private Node1 food;

public Gwin2()
{
//格子大小为20像素
//direction=new String("right");
snake1=new Snake1();
snake=snake1.getSnake();
food=snake1.getFood();
flag=false;
//direction=new String("right");
//direction=Direction.RIGHT;
//direction=Direction.RIGHT; //初始方向向右
//direction=Direction.DOWN;
/*
* 700/20=35
* 按钮要占空间
* 第一条线下移60像素,500-60=440,440/20=22
* 横排有35个格子要画竖线36条线,竖线第1条和第36条不要画
* 纵排有22个格子要画横线23条线,横线第23条不要画
* 则要画竖线34条,横线22条
* 0-700 60-500
* 设置区域大小和位置
*/
width=700;
height=500;
this.setSize(width, height);
this.setLocation((Win2.width-width)/2, (Win2.height-height)/2);
this.setBackground(Color.black);
//添加按钮组件
but_start=new JButton("开始");
but_stop=new JButton("暂停");
but_start.addActionListener(this);
but_stop.addActionListener(this);
this.add(but_start);
this.add(but_stop);
this.addKeyListener(this);
//启动线程
mythread=new Mythread();
thread=new Thread(mythread);
thread.start();
}
public void paint(Graphics g) //绘制
{
super.paint(g);

g.setColor(Color.red);
for(int i=1;i<35;i++) //竖线
{
g.drawLine(size*i, 60, size*i, 500);
}
for(int i=0;i<22;i++) //横线
{
g.drawLine(0, 60+size*i, 700, 60+size*i);
}

g.setColor(Color.white);
g.fillRect(food.getX(), food.getY(), size, size); //画食物
for(int i=0;i<snake.size();i++)
{
g.fillRect(snake.get(i).getX(), snake.get(i).getY(), size, size); //画蛇
}
}
public void actionPerformed(ActionEvent e)
{
Object source=e.getSource();
if(source==but_start)
{
flag=true;
}
else if(source==but_stop)
{
flag=false;
}
this.requestFocus(); //为jpanel获取事件,防止键盘监听无效
}
/*public enum Direction{ //枚举记录蛇头方向:上、下、左、右
UP,DOWN,RIGHT,LEFT;
}*/
public void keyPressed(KeyEvent e)
{
switch(e.getKeyCode())
{
case KeyEvent.VK_UP:direction="up";break;
case KeyEvent.VK_DOWN:direction="down";break;
case KeyEvent.VK_LEFT:direction="left";break;
case KeyEvent.VK_RIGHT:direction="right";break;
}

}
public void keyTyped(KeyEvent e) {}
public void keyReleased(KeyEvent e) {}
//内部类为线程类
class Mythread implements Runnable
{
public void run()
{
while(true)
{
//System.out.println(Gwin2.direction);
//System.out.println(flag);
if(flag)
{
//System.out.println(flag);
snake1.eatFood();
snake1.snakeMove();
try {
Thread.sleep(500);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//repaint();
}
repaint();
}
}
}
}

package Mysnake2;

import java.util.ArrayList;
import java.util.Random;

//import Mysnake2.Gwin2.Direction;

public class Snake1 {

private ArrayList<Node1> snake;
private int snakex=10*size,snakey=10*size+60; //初始蛇头位置
private int foodx=size*3,foody=60+size*5; //初始食物位置
public static final int length=3; //初始贪吃始长度
private Node1 food; //食物结点
private static final int size=Gwin2.size;
private Random rand;
private String direction;
//private Direction direction;
public Snake1()
{
snake=new ArrayList<Node1>();
food=new Node1(foodx,foody);
rand=new Random();
direction=Gwin2.direction;
initial();
}

public ArrayList<Node1> getSnake()
{
return snake;
}
public Node1 getFood()
{
return food;
}

public void initial() //初始化蛇位置和食物位置
{
snake.add(new Node1(snakex,snakey)); //添加蛇头
for(int i=1;i<length;i++)
{
int tempx=snakex-size*i;
int tempy=snakey;
snake.add(new Node1(tempx,tempy));
}
}

public void snakeMove() //刷新蛇位置
{
for(int i=snake.size()-1;i>0;i--)
{
snake.get(i).setX(snake.get(i-1).getX());
snake.get(i).setY(snake.get(i-1).getY());
}
/*int tempx=snake.get(0).getX();
int tempy=snake.get(0).getY();
snake.get(0).setX(tempx+x);
snake.get(0).setY(tempy+y);*/

if(direction.equals("up"))
{
System.out.println("按了上键");
snake.get(0).setX(snake.get(0).getX()+0);
snake.get(0).setY(snake.get(0).getY()-size);
}
else if(direction=="down")
{
System.out.println("按了下键");
snake.get(0).setX(snake.get(0).getX()+0);
snake.get(0).setY(snake.get(0).getY()+size);
}
else if(direction=="left")
{
snake.get(0).setX(snake.get(0).getX()-size);
snake.get(0).setY(snake.get(0).getY()+0);
}
else if(direction=="right")
{
snake.get(0).setX(snake.get(0).getX()+size);
snake.get(0).setY(snake.get(0).getY()+0);
}
}
public void foodChange() //刷新食物位置
{
food.setX(rand.nextInt(35)*size);
food.setY(rand.nextInt(22)*size+60);
}
/*
* 蛇吃了食物后会发生两件,1.刷新食物 2.蛇变长
*/
public void eatFood()
{
//蛇是否吃了食物
if(snake.get(0).getX()==food.getX()&&snake.get(0).getY()==food.getY())
{
//刷新食物
foodChange();
//蛇变长
Node1 newnode=snake.get(snake.size()-1);
snake.add(newnode);
}
}

}

package Mysnake2;

public class Node1 {

private int x,y;
public Node1() {}
public Node1(int x,int y)
{
this.x=x;
this.y=y;
}
public int getX()
{
return x;
}
public int getY()
{
return y;
}
public void setX(int x)
{
this.x=x;
}
public void setY(int y)
{
this.y=y;
}
}
...全文
183 3 打赏 收藏 转发到动态 举报
写回复
用AI写文章
3 条回复
切换为时间正序
请发表友善的回复…
发表回复
天涯若风 2019-01-11
  • 打赏
  • 举报
回复
定义全局变量
十八道胡同 2019-01-11
  • 打赏
  • 举报
回复
引用 1 楼 小小菜鸟肥 的回复:
用单例模式定义snake类,添加size变量,根据键盘输入来改变它,从而改变蛇头移动的位置


单例模式 是个办法

全局只有一个实例
小小菜鸟肥 2019-01-11
  • 打赏
  • 举报
回复
用单例模式定义snake类,添加size变量,根据键盘输入来改变它,从而改变蛇头移动的位置

62,621

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧