Extracted score logic into its own class.
[kong.git] / src / net / habraun / kong / Main.scala
blob84e6596b7d386133c1c0575f19602161b2d35891
1 /*
2 Copyright (c) 2008, 2009 Hanno Braun <hanno@habraun.net>
4 Licensed under the Apache License, Version 2.0 (the "License");
5 you may not use this file except in compliance with the License.
6 You may obtain a copy of the License at
8 http://www.apache.org/licenses/LICENSE-2.0
10 Unless required by applicable law or agreed to in writing, software
11 distributed under the License is distributed on an "AS IS" BASIS,
12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 See the License for the specific language governing permissions and
14 limitations under the License.
19 package net.habraun.kong
23 import java.awt._
24 import java.awt.geom._
25 import javax.swing._
27 import edu.umd.cs.piccolo._
28 import edu.umd.cs.piccolo.nodes._
29 import net.phys2d.math._
30 import net.phys2d.raw._
31 import net.phys2d.raw.shapes._
35 object Main {
37 val screenSizeX = 800
38 val screenSizeY = 600
40 val border = 20
42 val defaultStroke = new BasicStroke(0)
46 def main(args: Array[String]) {
47 // Configure the main window.
48 val frame = new JFrame("Kong 0.2")
49 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE)
50 frame.setSize(screenSizeX + 12, screenSizeY + 35)
52 // Configure the canvas where the scene graph is painted on.
53 val canvas = new PCanvas
54 canvas.removeInputEventListener(canvas.getZoomEventHandler)
55 canvas.removeInputEventListener(canvas.getPanEventHandler)
56 frame.add(canvas)
58 // Configure the background color.
59 val background = PPath.createRectangle(0, 0, screenSizeX, screenSizeY)
60 background.setPaint(Color.ORANGE)
61 canvas.getLayer.addChild(background)
63 // Configure the middle line.
64 val middleLine = PPath.createRectangle(screenSizeX / 2 - 1, 0, 2, screenSizeY)
65 middleLine.setPaint(Color.RED)
66 middleLine.setStroke(defaultStroke)
67 canvas.getLayer.addChild(middleLine)
69 // Configure the input handler
70 val inputHandler = new InputHandler
71 canvas.getRoot.getDefaultInputManager.setKeyboardFocus(inputHandler)
73 // Initialize paddles
74 val paddle1 = new Paddle(border + Paddle.radius, screenSizeY / 2)
75 val paddle2 = new Paddle(screenSizeX - border - Paddle.radius, screenSizeY / 2)
76 val paddles = paddle1::paddle2::Nil
78 // Initialize scene graph nodes for paddles
79 val paddleShape = new Ellipse2D.Double(0, 0, Paddle.radius * 2, Paddle.radius * 2)
80 val paddleNodes = paddles.map((paddle) => {
81 val node = new PPath(paddleShape)
82 node.setPaint(Color.RED)
83 node.setStroke(defaultStroke)
85 node
87 paddleNodes.foreach((node) => canvas.getLayer.addChild(node))
89 // Initialize the ball
90 val ball = new Ball(screenSizeX / 2, screenSizeY / 2)
91 ball.init
93 // Initialize the scene graph node for the ball
94 val ballShape = new Ellipse2D.Double(0, 0, Ball.radius * 2, Ball.radius * 2)
95 val ballNode = new PPath(ballShape)
96 ballNode.setPaint(Color.RED)
97 ballNode.setStroke(defaultStroke)
98 canvas.getLayer.addChild(ballNode)
100 // Initialize the borders
101 val borderShape = new Line(screenSizeX, 0)
102 val topBorder = new StaticBody(borderShape)
103 val bottomBorder = new StaticBody(borderShape)
104 topBorder.setPosition(0, 0)
105 bottomBorder.setPosition(0, screenSizeY)
106 topBorder.setFriction(0)
107 bottomBorder.setFriction(0)
108 topBorder.setRestitution(1)
109 bottomBorder.setRestitution(1)
111 // Initialize world for physics simulation and add all bodies
112 val world = new World(new Vector2f(0, 0), 1000)
113 paddles.foreach((paddle) => world.add(paddle.body))
114 world.add(ball.body)
115 world.add(topBorder)
116 world.add(bottomBorder)
118 // Initialize score
119 val score = new Score(screenSizeX / 2, screenSizeY / 2)
120 canvas.getLayer.addChild(score.node)
122 frame.setVisible(true)
123 canvas.requestFocusInWindow
125 // Game loop
126 while (true) {
127 // Process input
128 for (i <- 0 until paddles.length) {
129 if (inputHandler.isUpPressed(i)) {
130 paddles(i).movementUp
132 else if (inputHandler.isDownPressed(i)) {
133 paddles(i).movementDown
135 else {
136 paddles(i).movementStop
140 // Step the physics simulation
141 world.step
143 // Check if the ball left the field and needs to be placed in the middle again
144 val ballX = ball.body.getPosition.getX
145 if (ballX > screenSizeX) {
146 score.increaseScore1
147 ball.init
149 if (ballX < 0) {
150 score.increaseScore2
151 ball.init
154 // Display game state
155 SwingUtilities.invokeLater(new Runnable { def run {
156 for (i <- 0 until paddles.length) {
157 val position = paddles(i).body.getPosition
158 val x = position.getX - Paddle.radius
159 val y = position.getY - Paddle.radius
161 paddleNodes(i).setTransform(AffineTransform.getTranslateInstance(x, y))
164 val position = ball.body.getPosition
165 val x = position.getX - Ball.radius
166 val y = position.getY - Ball.radius
167 ballNode.setTransform(AffineTransform.getTranslateInstance(x, y))
169 score.update
172 Thread.sleep(17)