利用vb编写俄罗斯方块

利用vb编写俄罗斯方块,第1张

/**

* File: ErsBlocksGame.java

* User: 张丽琼

* Date: May 11, 2009

* Describe: 俄罗斯方块的Java实现

*/

package src

import javax.swing.*

import java.awt.*

import java.awt.event.*

/**

* 游戏主类,继承自JFrame类,负责游戏的全局控制。

* 内含

* 1, 一个GameCanvas画布类的实例引用,

* 2, 一个保存当前活动块(ErsBlock)实例的引用,

* 3, 一个保存当前控制面板(ControlPanel)实例的引用

*/

public class ErsBlocksGame extends JFrame {

/**

* 每填满一行计多少分(每填满一行计100分)

*/

public final static int PER_LINE_SCORE = 100

/**

* 积多少分以后能升级(积满100*20分以后升一级)

*/

public final static int PER_LEVEL_SCORE = PER_LINE_SCORE * 20

/**

* 最大级数是10级

*/

public final static int MAX_LEVEL = 10

/**

* 默认级数是5

*/

public final static int DEFAULT_LEVEL = 5

private GameCanvas canvas//画布类

private ErsBlock block//块类

private boolean playing = false

private ControlPanel ctrlPanel//控制面板类

/**

* javax.swing.JMenuBar菜单栏的实现。将JMenu对象添加到菜单栏以构造菜单。

*当用户选择JMenu对象时,就会显示其关联的JPopupMenu,允许用户选择其上的某一个JMenuItem。

*/

private JMenuBar bar = new JMenuBar()

/**

* javax.swing.JMenu菜单的该实现是一个包含 JMenuItem 的d出窗口

* 用户选择 JMenuBar 上的项时会显示该 JMenuItem。除 JMenuItem 之外,

* JMenu 还可以包含 JSeparator。

*/

private JMenu

mGame = new JMenu("Game"),

mControl = new JMenu("Control"),

mWindowStyle = new JMenu("WindowStyle"),

mInfo = new JMenu("Information")

/**

* javax.swing.JMenuItem菜单中的项的实现。菜单项本质上是位于列表中的按钮。

* 当用户选择“按钮”时,则执行与菜单项关联的 *** 作。JPopupMenu 中包含的 JMenuItem 正好执行该功能。

*/

private JMenuItem

miNewGame = new JMenuItem("New Game"),

miSetBlockColor = new JMenuItem("Set Block Color ..."),

miSetBackColor = new JMenuItem("Set Background Color ..."),

miTurnHarder = new JMenuItem("Turn up the level"),

miTurnEasier = new JMenuItem("Turn down the level"),

miExit = new JMenuItem("Eixt"),

miPlay = new JMenuItem("Play"),

miPause = new JMenuItem("Pause"),

miResume = new JMenuItem("Resume"),

miStop = new JMenuItem("Stop"),

miAuthor = new JMenuItem("Author : zlq87229@163.com"),

miSourceInfo = new JMenuItem("You can get the source code / document by email")

/**

* javax.swing.JCheckBoxMenuItem可以被选定或取消选定的菜单项。

* 如果被选定,菜单项的旁边通常会出现一个复选标记。如果未被选定或被取消选定,

* 菜单项的旁边就没有复选标记。像常规菜单项一样,复选框菜单项可以有与之关联的文本或图标,

* 或者二者兼而有之。

*/

private JCheckBoxMenuItem

miAsWindows = new JCheckBoxMenuItem("Windows"),

miAsMotif = new JCheckBoxMenuItem("Motif"),

miAsMetal = new JCheckBoxMenuItem("Metal", true)//true默认是显示的这个Metal

/**

* 主游戏类的构造函数

* @param title String,窗口标题

*/

public ErsBlocksGame(String title) {

super(title)

//setSize(315, 392)//设置组件窗口的尺寸大小。

setSize(315,392)

/**

* java.awt.Toolkit此类是所有 Abstract Window Toolkit 实际实现的抽象超类。

* Toolkit 的子类被用于将各种组件绑定到特定本机工具包实现。

*/

Dimension scrSize = Toolkit.getDefaultToolkit().getScreenSize()// 获取屏幕的大小。

/**

* java.awt.Component.setLocation将组件移到新位置。

* java.awt.Component.getSize 以 Dimension 对象的形式返回组件的大小。

* 这里是设置游戏窗口在屏幕上位置。

*/

setLocation((scrSize.width - getSize().width) / 2,

(scrSize.height - getSize().height) / 2)

createMenu()//此方法在下面定义

/**

* Container javax.swing.JFrame.getContentPane() 返回此窗体的 contentPane 对象

*/

Container container = getContentPane()

container.setLayout(new BorderLayout(6,0))

canvas = new GameCanvas(20,12)

ctrlPanel = new ControlPanel(this)

container.add(canvas, BorderLayout.CENTER)//窗口的而局

container.add(ctrlPanel, BorderLayout.EAST)

/**

* void java.awt.Window.addWindowListener(WindowListener l)

* 添加指定的窗口侦听器,以从此窗口接收窗口事件。

*/

addWindowListener(new WindowAdapter() {

public void windowClosing(WindowEvent we) {

stopGame()//这个方法是自定义的,在下面有。

System.exit(0)

}

})

/**

* void java.awt.Component.addComponentListener(ComponentListener l)

* 添加指定的组件侦听器,以接收发自此组件的组件事件。

*/

addComponentListener(new ComponentAdapter() {

public void componentResized(ComponentEvent ce) {

canvas.fanning()//此方法在GameCanvas类中定义

}

})

//show()//此方法在JDK1.5过时了,采用下面这个方法。

setVisible(true)

canvas.fanning()

}//主游戏类的构造函数到这里写完了

/**

* 让游戏“复位”

*/

public void reset() {

ctrlPanel.reset()

canvas.reset()

}

/**

* 判断游戏是否还在进行

* @return boolean, true-还在运行,false-已经停止

*/

public boolean isPlaying() {

return playing

}

/**

* 得到当前活动的块

* @return ErsBlock, 当前活动块的引用

*/

public ErsBlock getCurBlock() {

return block

}

/**

* 得到当前画布

* @return GameCanvas, 当前画布的引用

*/

public GameCanvas getCanvas() {

return canvas

}

/**

* 开始游戏

*/

public void playGame() {

play()//此方法是自己定义的,在下面

ctrlPanel.setPlayButtonEnable(false)//游戏开始以后禁用“play”按钮。

/**

* void javax.swing.JMenuItem.setEnabled(boolean b)启用或禁用菜单项。

* 在游戏开始以后这个菜单项就不能用了,设置为false.

*/

miPlay.setEnabled(false)

ctrlPanel.requestFocus()// 请求此 Component 获取输入焦点。

}

/**

* 游戏暂停

*/

public void pauseGame() {

if (block != null) block.pauseMove()

ctrlPanel.setPauseButtonLabel(false)

miPause.setEnabled(false)

miResume.setEnabled(true)

}

/**

* 让暂停中的游戏继续

*/

public void resumeGame() {

if (block != null) block.resumeMove()

ctrlPanel.setPauseButtonLabel(true)

miPause.setEnabled(true)

miResume.setEnabled(false)

ctrlPanel.requestFocus()

}

/**

* 用户停止游戏

*/

public void stopGame() {

playing = false

if (block != null) block.stopMove()

miPlay.setEnabled(true)

miPause.setEnabled(true)

miResume.setEnabled(false)

ctrlPanel.setPlayButtonEnable(true)

ctrlPanel.setPauseButtonLabel(true)

}

/**

* 得到当前游戏者设置的游戏难度

* @return int, 游戏难度1-MAX_LEVEL

*/

public int getLevel() {

return ctrlPanel.getLevel()

}

/**

* 让用户设置游戏难度

* @param level int, 游戏难度1-MAX_LEVEL

*/

public void setLevel(int level) {

if (level <11 &&level >0) ctrlPanel.setLevel(level)

}

/**

* 得到游戏积分

* @return int, 积分。

*/

public int getScore() {

if (canvas != null) return canvas.getScore()

return 0

}

/**

* 得到自上次升级以来的游戏积分,升级以后,此积分清零

* @return int, 积分。

*/

public int getScoreForLevelUpdate() {

if (canvas != null) return canvas.getScoreForLevelUpdate()

return 0

}

/**

* 当分数累计到一定的数量时,升一次级

* @return boolean, ture-update successufl, false-update fail

*/

public boolean levelUpdate() {

int curLevel = getLevel()

if (curLevel <MAX_LEVEL) {

setLevel(curLevel + 1)

canvas.resetScoreForLevelUpdate()

return true

}

return false

}

/**

* 游戏开始

*/

private void play() {

reset()

playing = true

Thread thread = new Thread(new Game())

thread.start()

}

/**

* 报告游戏结束了

*/

private void reportGameOver() {

JOptionPane.showMessageDialog(this, "Game Over!")

}

/**

* 建立并设置窗口菜单

*/

private void createMenu() {

bar.add(mGame)

bar.add(mControl)

bar.add(mWindowStyle)

bar.add(mInfo)

mGame.add(miNewGame)

mGame.addSeparator()

mGame.add(miSetBlockColor)

mGame.add(miSetBackColor)

mGame.addSeparator()

mGame.add(miTurnHarder)

mGame.add(miTurnEasier)

mGame.addSeparator()

mGame.add(miExit)

mControl.add(miPlay)

mControl.add(miPause)

mControl.add(miResume)

mControl.add(miStop)

mWindowStyle.add(miAsWindows)

mWindowStyle.add(miAsMotif)

mWindowStyle.add(miAsMetal)

mInfo.add(miAuthor)

mInfo.add(miSourceInfo)

setJMenuBar(bar)

miPause.setAccelerator(

KeyStroke.getKeyStroke(KeyEvent.VK_P, KeyEvent.CTRL_MASK))

miResume.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0))

miNewGame.addActionListener(new ActionListener() {

public void actionPerformed(ActionEvent ae) {

stopGame()

reset()

setLevel(DEFAULT_LEVEL)

}

})

miSetBlockColor.addActionListener(new ActionListener() {

public void actionPerformed(ActionEvent ae) {

Color newFrontColor =

JColorChooser.showDialog(ErsBlocksGame.this,

"Set color for block", canvas.getBlockColor())

if (newFrontColor != null)

canvas.setBlockColor(newFrontColor)

}

})

miSetBackColor.addActionListener(new ActionListener() {

public void actionPerformed(ActionEvent ae) {

Color newBackColor =

JColorChooser.showDialog(ErsBlocksGame.this,

"Set color for block", canvas.getBackgroundColor())

if (newBackColor != null)

canvas.setBackgroundColor(newBackColor)

}

})

miTurnHarder.addActionListener(new ActionListener() {

public void actionPerformed(ActionEvent ae) {

int curLevel = getLevel()

if (curLevel <MAX_LEVEL) setLevel(curLevel + 1)

}

})

miTurnEasier.addActionListener(new ActionListener() {

public void actionPerformed(ActionEvent ae) {

int curLevel = getLevel()

if (curLevel >1) setLevel(curLevel - 1)

}

})

miExit.addActionListener(new ActionListener() {

public void actionPerformed(ActionEvent ae) {

System.exit(0)

}

})

miPlay.addActionListener(new ActionListener() {

public void actionPerformed(ActionEvent ae) {

playGame()

}

})

miPause.addActionListener(new ActionListener() {

public void actionPerformed(ActionEvent ae) {

pauseGame()

}

})

miResume.addActionListener(new ActionListener() {

public void actionPerformed(ActionEvent ae) {

resumeGame()

}

})

miStop.addActionListener(new ActionListener() {

public void actionPerformed(ActionEvent ae) {

stopGame()

}

})

miAsWindows.addActionListener(new ActionListener() {

public void actionPerformed(ActionEvent ae) {

String plaf = "com.sun.java.swing.plaf.windows.WindowsLookAndFeel"

setWindowStyle(plaf)

canvas.fanning()

ctrlPanel.fanning()

miAsWindows.setState(true)

miAsMetal.setState(false)

miAsMotif.setState(false)

}

})

miAsMotif.addActionListener(new ActionListener() {

public void actionPerformed(ActionEvent ae) {

String plaf = "com.sun.java.swing.plaf.motif.MotifLookAndFeel"

setWindowStyle(plaf)

canvas.fanning()

ctrlPanel.fanning()

miAsWindows.setState(false)

miAsMetal.setState(false)

miAsMotif.setState(true)

}

})

miAsMetal.addActionListener(new ActionListener() {

public void actionPerformed(ActionEvent ae) {

String plaf = "javax.swing.plaf.metal.MetalLookAndFeel"

setWindowStyle(plaf)

canvas.fanning()

ctrlPanel.fanning()

miAsWindows.setState(false)

miAsMetal.setState(true)

miAsMotif.setState(false)

}

})

}

/**

* 根据字串设置窗口外观

* @param plaf String, 窗口外观的描述

*/

private void setWindowStyle(String plaf) {

try {

UIManager.setLookAndFeel(plaf)

SwingUtilities.updateComponentTreeUI(this)

} catch (Exception e) {

}

}

/**

* 一轮游戏过程,实现了Runnable接口

* 一轮游戏是一个大循环,在这个循环中,每隔100毫秒,

* 检查游戏中的当前块是否已经到底了,如果没有,

* 就继续等待。如果到底了,就看有没有全填满的行,

* 如果有就删除它,并为游戏者加分,同时随机产生一个

* 新的当前块,让它自动下落。

* 当新产生一个块时,先检查画布最顶上的一行是否已经

* 被占了,如果是,可以判断Game Over了。

*/

private class Game implements Runnable {

public void run() {

int col = (int) (Math.random() * (canvas.getCols() - 3)),

style = ErsBlock.STYLES[(int) (Math.random() * 7)][(int) (Math.random() * 4)]

while (playing) {

if (block != null) {//第一次循环时,block为空

if (block.isAlive()) {

try {

Thread.currentThread().sleep(100)

} catch (InterruptedException ie) {

ie.printStackTrace()

}

continue

}

}

checkFullLine() //检查是否有全填满的行

if (isGameOver()) { //检查游戏是否应该结束了

miPlay.setEnabled(true)

miPause.setEnabled(true)

miResume.setEnabled(false)

ctrlPanel.setPlayButtonEnable(true)

ctrlPanel.setPauseButtonLabel(true)

reportGameOver()

return

}

block = new ErsBlock(style, -1, col, getLevel(), canvas)

block.start()

col = (int) (Math.random() * (canvas.getCols() - 3))

style = ErsBlock.STYLES[(int) (Math.random() * 7)][(int) (Math.random() * 4)]

ctrlPanel.setTipStyle(style)

}

}

/**

* 检查画布中是否有全填满的行,如果有就删除之

*/

public void checkFullLine() {

for (int i = 0i <canvas.getRows()i++) {

int row = -1

boolean fullLineColorBox = true

for (int j = 0j <canvas.getCols()j++) {

if (!canvas.getBox(i, j).isColorBox()) {

fullLineColorBox = false

break

}

}

if (fullLineColorBox) {

row = i--

canvas.removeLine(row)

}

}

}

/**

* 根据最顶行是否被占,判断游戏是否已经结束了。

* @return boolean, true-游戏结束了,false-游戏未结束

*/

private boolean isGameOver() {

for (int i = 0i <canvas.getCols()i++) {

ErsBox box = canvas.getBox(0, i)

if (box.isColorBox()) return true

}

return false

}

}

}

考虑到美观与功能,所以用到的用到的组件有colorbox,paintbox,panel.panitbox1放在panel上面。

线条的颜色可以随时改变。所以增加了其灵活性。

var

x,y:integer

begin

x := 50

y := Height div 2

paintbox1.Canvas.Pen.Color := colorbox1.Selected

paintbox1.Canvas.Brush.Color:=colorbox1.Selected

paintbox1.Canvas.MoveTo(x,y)

paintbox1.Canvas.LineTo(x + 90, y)

end


欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/bake/7929567.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2023-04-11
下一篇2023-04-11

发表评论

登录后才能评论

评论列表(0条)

    保存