如何动态更新在Java中使用MyCanvas创建的GUI?我正在尝试编写一款名为Lotus的棋盘游戏。
这是游戏的描述: 玩家试图从游戏轨道的起始区域到终点区域操纵他们的游戏棋子(双人游戏中的10个,三人或四人游戏中的六个)。碎片移动的空间数等于它们堆叠的其他碎片的数量。只有堆叠顶部的那块可能会移动。游戏轨道有两个入口,但只有一条通往终点区的路线。该赛道包含一个“蹦床”空间,允许玩家在着陆时加倍移动距离。第一个移除所有棋子的玩家获胜。
基本上,我到目前为止有两节课。 GameEngine类和GUI类。
GameEngine.java
package GameEngine;
import java.awt.Canvas;
import java.awt.Color;
import java.awt.Graphics;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Stack;
import java.util.Timer;
import javax.swing.JFrame;
import GUI.MyCanvas;
/**
* Lotus Game Engine
*
* Functionality:
* 1) Generates a GUI and modifies it in real-time based on player input through the Finch.
* 2) Tracks whose current turn it is.
* 3) Manages all game pieces on the Lotus game board.
* 4) Determines when a player has won the game.
*
*
*/
public class GameEngine extends Canvas {
// Instantiate a few variables
boolean isRunning = true; // Game is currently active
private java.util.Timer timer;
/* Create 25 stacks that correspond to each position on the game board
ArrayList<Stack<Integer>>[] positions = new ArrayList<Stack<Integer>>[25];
public GameEngine() {
for (int i=0; i<positions.length; i++) {
positions[i] = new Stack<?>();
}
}
*/
//The following 8 Stacks are named using the following conventions:
//posS## - The 'S' indicated that this is one of the starting Stacks.
// - The first number indicates the player (1 or 0)
// - The second number indicates the size of the starting stack (1, 2, 3, or 4)
StackByCompositionWithArrayList<Integer> posS01 = new StackByCompositionWithArrayList<Integer>();
StackByCompositionWithArrayList<Integer> posS02 = new StackByCompositionWithArrayList<Integer>();
StackByCompositionWithArrayList<Integer> posS03 = new StackByCompositionWithArrayList<Integer>();
StackByCompositionWithArrayList<Integer> posS04 = new StackByCompositionWithArrayList<Integer>();
StackByCompositionWithArrayList<Integer> posS11 = new StackByCompositionWithArrayList<Integer>();
StackByCompositionWithArrayList<Integer> posS12 = new StackByCompositionWithArrayList<Integer>();
StackByCompositionWithArrayList<Integer> posS13 = new StackByCompositionWithArrayList<Integer>();
StackByCompositionWithArrayList<Integer> posS14 = new StackByCompositionWithArrayList<Integer>();
// Launch GUI
public static void main(String[] args){
MyCanvas c = new MyCanvas();
JFrame frame = new JFrame();
frame.setSize(420, 420);
frame.setDefaultCloseOperation(frame.EXIT_ON_CLOSE);
frame.getContentPane().add(c);
frame.setVisible(true);
}
//Loads proper number of game pieces (0's and 1's) into starting stack positions.
public void setUpStacks(){
//Single Stacks
posS01.push(0);
posS11.push(1);
//Double Stacks
for (int x = 0; x < 2; x++){
posS02.push(0);
posS12.push(1);
}
//Triple Stacks
for (int x = 0; x < 3; x++){
posS03.push(0);
posS13.push(1);
}
//Quad Stacks
for (int x = 0; x < 4; x++){
posS04.push(0);
posS14.push(1);
}
}
//@author rshannon
public void gameLoop()
{
timer = new Timer();
timer.schedule(new GameLoop(), 0, 1000 / 60); //new timer at 60 fps, the timing mechanism
}
private class GameLoop extends java.util.TimerTask
{
public void run() { // this becomes the loop
/*
if(pos24counter==10 || pos25counter==10){
isRunning = false;
}
*/
if (!isRunning){
timer.cancel(); // Stop timer
//declareWinner(); // Declare winner
}
}
}
public void Updater (StackByCompositionWithArrayList<Integer> stack, int position, boolean player, Graphics g){
int distance = stack.size();
//PLAYER 1 == TRUE == BLUE == 1
//PLAYER 2 == FALSE == RED == 0
int finalPosition;
if (position == 15){
position = position - 3;
}
if ((position == 16) && (distance > 1)){
position = position - 3;
}
if ((position == 17) && (distance > 2)){
position = position - 3;
}
finalPosition = position + distance;
if (finalPosition == 1){
pos1.push(stack.pop());
}
if (finalPosition == 2){
pos2.push(stack.pop());
}
if (finalPosition == 3){
pos3.push(stack.pop());
}
if (finalPosition == 4){
pos4.push(stack.pop());
}
if (finalPosition == 5){
pos5.push(stack.pop());
}
if (finalPosition == 6){
pos6.push(stack.pop());
}
if (finalPosition == 7){
pos7.push(stack.pop());
}
if (finalPosition == 8){
pos8.push(stack.pop());
}
if (finalPosition == 9){
pos9.push(stack.pop());
}
if (finalPosition == 10){
pos10.push(stack.pop());
}
if (finalPosition == 11){
pos11.push(stack.pop());
}
if (finalPosition == 12){
pos12.push(stack.pop());
}
if (finalPosition == 13){
pos13.push(stack.pop());
}
if (finalPosition == 14){
pos14.push(stack.pop());
}
if (finalPosition == 15){
pos15.push(stack.pop());
}
if (finalPosition == 16){
pos16.push(stack.pop());
}
if (finalPosition == 17){
pos17.push(stack.pop());
}
//*************************************************************************************************************\\
//*************************************************************************************************************\\
//*************************************************************************************************************\\
//*************************************************************************************************************\\
//*************************************************************************************************************\\
//Could make it so the GUI Updater method continuously peeks at each stack, it it
//returns 1 then the circle should be blue, if it returns 0 then the circle should
//be red, and else, it sets the circle to black (empty.)
//OR
//Could make it so the Updater Class executes only when a Finch interaction is made
//In this case, the parameters would include the stack where the position is, (we will
//need to know the size of the stack, so I think we should implement a size method in
//the StackByCompositionWithArrayList Class definition.) Also, we will need to a boolean
//value to determine which player's turn it is. This method will need access to all of the
//position stacks (pos1-pos25.) I think that this class should be written in the GameEngine
//class.
if(distance > 1){
if (player == true){
}
else{
}
}
}
}
GUI.java
package GUI;
import java.awt.GridLayout;
import javax.swing.JFrame;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import java.util.Random;
import javax.swing.*;
import GameEngine.StackByCompositionWithArrayList;
public class MyCanvas extends Canvas{
public MyCanvas(){
}
public void paint(Graphics g){
g.setColor(Color.black);
g.drawLine(30, 100, 100, 30);
g.drawLine(300, 30, 100, 30);
g.drawLine(300, 30, 370, 100);
g.drawLine(370, 350, 370, 100);
g.drawLine(370, 350, 320, 350);
g.drawLine(320, 120, 320, 350);
g.drawLine(320, 120, 280, 80);
g.drawLine(120, 80, 280, 80);
g.drawLine(120, 80, 80, 120);
g.drawLine(80, 120, 80, 250);
g.drawLine(80, 250, 100, 270);
g.drawLine(170, 270, 100, 270);
//Breaking pattern, moving to Left most line.
g.drawLine(30, 100, 30, 270);
g.drawLine(30, 270, 80, 320);
g.drawLine(230, 320, 80, 320);
g.drawLine(230, 320, 230, 250);
g.drawLine(300, 250, 230, 250);
g.drawLine(300, 250, 300, 130);
g.drawLine(250, 130, 300, 130);
g.drawLine(250, 130, 250, 200);
g.drawLine(150, 200, 250, 200);
//Breaking pattern, moving to smallest vertical line.
g.drawLine(170, 270, 170, 250);
g.drawLine(100, 250, 170, 250);
g.drawLine(100, 250, 100, 130);
g.drawLine(150, 130, 100, 130);
g.drawLine(150, 130, 150, 200);
g.fillOval(110,140,30,30); //14
g.fillOval(110,180,30,30); //13
g.fillOval(140,210,30,30); //12
g.fillOval(185,210,30,30); //11
g.fillOval(260,140,30,30); //17
g.fillOval(260,180,30,30); //16
g.fillOval(230,210,30,30); //15
g.fillOval(185,280,30,30); //10
g.fillOval(80,280,30,30); //9
g.fillOval(40,210,30,30); //8
g.fillOval(40,130,30,30); //7
g.fillOval(80,55,30,30); //6
g.fillOval(185,40,30,30); //5
g.fillOval(290,55,30,30); //4
g.fillOval(330,130,30,30); //3
g.fillOval(330,210,30,30); //2
g.fillOval(330,290,30,30); //1
}
public void test(Graphics g){
g.setColor(Color.red);
g.fillOval(330,210,30,30); //2
g.fillOval(330,290,30,30); //1
}
}
当我在GUI.java中调用测试方法时,它不会更新GUI?
我对这个烂摊子有什么建议吗?
答案 0 :(得分:1)
使用Swing JPanel代替AWT Canvas
覆盖JPanel的paintComponent而不是Canvas
将所有绘画放入数组中,在执行paintComponent / paint之前准备,在paintComponent / paint中仅在此数组内循环
回答你的问题是添加代码行super.paint(g);,然后清除旧画并且显示新的