如何在Java中使用MyCanvas创建动态更新的GUI?

时间:2013-04-03 06:27:43

标签: java swing awt java-2d mixing

如何动态更新在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?

我对这个烂摊子有什么建议吗?

1 个答案:

答案 0 :(得分:1)

  1. 使用Swing JPanel代替AWT Canvas

  2. 覆盖JPanel的paintComponent而不是Canvas

  3. 的paint
  4. 将所有绘画放入数组中,在执行paintComponent / paint之前准备,在paintComponent / paint中仅在此数组内循环

  5. 回答你的问题是添加代码行super.paint(g);,然后清除旧画并且显示新的