├── nbproject ├── private │ ├── config.properties │ ├── private.properties │ └── private.xml ├── genfiles.properties ├── project.xml └── project.properties ├── piraha.jar ├── manifest.mf └── src ├── basicgraphics ├── sounds │ ├── 1.wav │ ├── 2.wav │ ├── 3.wav │ ├── 4.wav │ ├── 5.wav │ ├── 6.wav │ ├── 7.wav │ ├── 8.wav │ ├── die.wav │ ├── arrow.wav │ ├── beep.wav │ ├── tanks │ │ ├── boom.wav │ │ └── shot.wav │ ├── SoundPlayer.java │ └── ReusableClip.java ├── images │ ├── bat.png │ ├── dog.jpg │ ├── claw.png │ ├── park.jpg │ ├── park2.jpg │ ├── pawn2.png │ ├── sarah.png │ ├── mfalcon.png │ ├── scenery.jpeg │ ├── ant-small.png │ ├── freespace.png │ ├── tiefighter.png │ ├── IconImage.java │ ├── Painter.java │ ├── RuntimeIOException.java │ ├── BackgroundPainter.java │ └── Picture.java ├── CollisionState.java ├── CollisionEventType.java ├── SpriteSpriteCollisionListener.java ├── BasicLayoutException.java ├── PaintRegion.java ├── GuiException.java ├── examples │ ├── Foo.java │ ├── Bat.java │ ├── BasicGraphics.java │ └── BasicGraphics2.java ├── Card.java ├── Bounds.java ├── BadComponent.java ├── ErrorComponent.java ├── SpriteCollisionEvent.java ├── KeyWrapper.java ├── Task.java ├── Util.java ├── Scene.java ├── MouseWrapper.java ├── ClockWorker.java ├── FileUtility.java ├── calculator │ ├── Auto.java │ ├── MarsData.java │ ├── Calculator.java │ └── CalcTester.java ├── TaskRunner.java ├── BasicDialog.java ├── ByNameLayout.java ├── cards │ └── CardLayoutExample.java ├── BasicContainer.java ├── BasicLayout.java └── Sprite.java ├── boardgame ├── Player.java ├── MoveListener.java ├── Piece.java ├── Move.java ├── Game.java └── Board.java ├── prog └── game │ ├── board.txt │ ├── prog.peg │ ├── ProgSpriteComponent.java │ └── Dice.java ├── basicshooter ├── Shooter.java ├── Bullet.java ├── Enemy.java └── Game.java ├── maze ├── Cell.java ├── Pos.java ├── MazePathFinder.java ├── PathFinder.java ├── MazeViz.java └── Maze.java ├── robosorter ├── MartianEgg.java ├── Robo.java ├── Mover.java ├── Board.java └── EggSorter.java ├── basicflyer ├── Plasma.java ├── Falcon.java └── Flyer.java ├── langtonsant ├── AntSprite.java └── Ant.java ├── lightsout ├── LightsOutGame.java └── Tile.java ├── trees └── BTree.java └── walkthedog └── WalkDog.java /nbproject/private/config.properties: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /piraha.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stevenrbrandt/BasicGraphics/main/piraha.jar -------------------------------------------------------------------------------- /manifest.mf: -------------------------------------------------------------------------------- 1 | Manifest-Version: 1.0 2 | X-COMMENT: Main-Class will be added automatically by build 3 | 4 | -------------------------------------------------------------------------------- /src/basicgraphics/sounds/1.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stevenrbrandt/BasicGraphics/main/src/basicgraphics/sounds/1.wav -------------------------------------------------------------------------------- /src/basicgraphics/sounds/2.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stevenrbrandt/BasicGraphics/main/src/basicgraphics/sounds/2.wav -------------------------------------------------------------------------------- /src/basicgraphics/sounds/3.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stevenrbrandt/BasicGraphics/main/src/basicgraphics/sounds/3.wav -------------------------------------------------------------------------------- /src/basicgraphics/sounds/4.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stevenrbrandt/BasicGraphics/main/src/basicgraphics/sounds/4.wav -------------------------------------------------------------------------------- /src/basicgraphics/sounds/5.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stevenrbrandt/BasicGraphics/main/src/basicgraphics/sounds/5.wav -------------------------------------------------------------------------------- /src/basicgraphics/sounds/6.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stevenrbrandt/BasicGraphics/main/src/basicgraphics/sounds/6.wav -------------------------------------------------------------------------------- /src/basicgraphics/sounds/7.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stevenrbrandt/BasicGraphics/main/src/basicgraphics/sounds/7.wav -------------------------------------------------------------------------------- /src/basicgraphics/sounds/8.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stevenrbrandt/BasicGraphics/main/src/basicgraphics/sounds/8.wav -------------------------------------------------------------------------------- /src/basicgraphics/images/bat.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stevenrbrandt/BasicGraphics/main/src/basicgraphics/images/bat.png -------------------------------------------------------------------------------- /src/basicgraphics/images/dog.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stevenrbrandt/BasicGraphics/main/src/basicgraphics/images/dog.jpg -------------------------------------------------------------------------------- /src/basicgraphics/sounds/die.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stevenrbrandt/BasicGraphics/main/src/basicgraphics/sounds/die.wav -------------------------------------------------------------------------------- /src/basicgraphics/images/claw.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stevenrbrandt/BasicGraphics/main/src/basicgraphics/images/claw.png -------------------------------------------------------------------------------- /src/basicgraphics/images/park.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stevenrbrandt/BasicGraphics/main/src/basicgraphics/images/park.jpg -------------------------------------------------------------------------------- /src/basicgraphics/images/park2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stevenrbrandt/BasicGraphics/main/src/basicgraphics/images/park2.jpg -------------------------------------------------------------------------------- /src/basicgraphics/images/pawn2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stevenrbrandt/BasicGraphics/main/src/basicgraphics/images/pawn2.png -------------------------------------------------------------------------------- /src/basicgraphics/images/sarah.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stevenrbrandt/BasicGraphics/main/src/basicgraphics/images/sarah.png -------------------------------------------------------------------------------- /src/basicgraphics/sounds/arrow.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stevenrbrandt/BasicGraphics/main/src/basicgraphics/sounds/arrow.wav -------------------------------------------------------------------------------- /src/basicgraphics/sounds/beep.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stevenrbrandt/BasicGraphics/main/src/basicgraphics/sounds/beep.wav -------------------------------------------------------------------------------- /src/basicgraphics/images/mfalcon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stevenrbrandt/BasicGraphics/main/src/basicgraphics/images/mfalcon.png -------------------------------------------------------------------------------- /src/basicgraphics/images/scenery.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stevenrbrandt/BasicGraphics/main/src/basicgraphics/images/scenery.jpeg -------------------------------------------------------------------------------- /src/basicgraphics/images/ant-small.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stevenrbrandt/BasicGraphics/main/src/basicgraphics/images/ant-small.png -------------------------------------------------------------------------------- /src/basicgraphics/images/freespace.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stevenrbrandt/BasicGraphics/main/src/basicgraphics/images/freespace.png -------------------------------------------------------------------------------- /src/basicgraphics/images/tiefighter.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stevenrbrandt/BasicGraphics/main/src/basicgraphics/images/tiefighter.png -------------------------------------------------------------------------------- /src/basicgraphics/sounds/tanks/boom.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stevenrbrandt/BasicGraphics/main/src/basicgraphics/sounds/tanks/boom.wav -------------------------------------------------------------------------------- /src/basicgraphics/sounds/tanks/shot.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stevenrbrandt/BasicGraphics/main/src/basicgraphics/sounds/tanks/shot.wav -------------------------------------------------------------------------------- /nbproject/private/private.properties: -------------------------------------------------------------------------------- 1 | compile.on.save=false 2 | do.depend=false 3 | do.jar=true 4 | do.jlink=true 5 | javac.debug=true 6 | javadoc.preview=true 7 | jlink.strip=false 8 | user.properties.file=C:\\Users\\steve\\AppData\\Roaming\\NetBeans\\24\\build.properties 9 | work.dir=./build/classes 10 | -------------------------------------------------------------------------------- /src/boardgame/Player.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this license header, choose License Headers in Project Properties. 3 | * To change this template file, choose Tools | Templates 4 | * and open the template in the editor. 5 | */ 6 | package boardgame; 7 | 8 | /** 9 | * 10 | * @author sbrandt 11 | */ 12 | public interface Player { 13 | Move getMove(); 14 | } 15 | -------------------------------------------------------------------------------- /src/basicgraphics/CollisionState.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this license header, choose License Headers in Project Properties. 3 | * To change this template file, choose Tools | Templates 4 | * and open the template in the editor. 5 | */ 6 | package basicgraphics; 7 | 8 | /** 9 | * 10 | * @author sbrandt 11 | */ 12 | enum CollisionState { 13 | OLD, NEW 14 | } 15 | -------------------------------------------------------------------------------- /src/basicgraphics/images/IconImage.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this license header, choose License Headers in Project Properties. 3 | * To change this template file, choose Tools | Templates 4 | * and open the template in the editor. 5 | */ 6 | package basicgraphics.images; 7 | 8 | /** 9 | * 10 | * @author sbrandt 11 | */ 12 | public class IconImage { 13 | 14 | } 15 | -------------------------------------------------------------------------------- /src/boardgame/MoveListener.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this license header, choose License Headers in Project Properties. 3 | * To change this template file, choose Tools | Templates 4 | * and open the template in the editor. 5 | */ 6 | package boardgame; 7 | 8 | /** 9 | * 10 | * @author sbrandt 11 | */ 12 | public interface MoveListener { 13 | void moveMade(Move m); 14 | } 15 | -------------------------------------------------------------------------------- /src/basicgraphics/CollisionEventType.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this license header, choose License Headers in Project Properties. 3 | * To change this template file, choose Tools | Templates 4 | * and open the template in the editor. 5 | */ 6 | package basicgraphics; 7 | 8 | /** 9 | * 10 | * @author sbrandt 11 | */ 12 | public enum CollisionEventType { 13 | WALL, WALL_INVISIBLE; 14 | } 15 | -------------------------------------------------------------------------------- /src/basicgraphics/SpriteSpriteCollisionListener.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this license header, choose License Headers in Project Properties. 3 | * To change this template file, choose Tools | Templates 4 | * and open the template in the editor. 5 | */ 6 | package basicgraphics; 7 | 8 | /** 9 | * 10 | * @author sbrandt 11 | */ 12 | public interface SpriteSpriteCollisionListener { 13 | void collision(T1 sp1,T2 sp2); 14 | } 15 | -------------------------------------------------------------------------------- /src/basicgraphics/BasicLayoutException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this license header, choose License Headers in Project Properties. 3 | * To change this template file, choose Tools | Templates 4 | * and open the template in the editor. 5 | */ 6 | package basicgraphics; 7 | 8 | /** 9 | * 10 | * @author sbrandt 11 | */ 12 | class BasicLayoutException extends RuntimeException { 13 | 14 | public BasicLayoutException(String string) { 15 | super(string); 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /src/basicgraphics/images/Painter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Click nbfs://nbhost/SystemFileSystem/Templates/Licenses/license-default.txt to change this license 3 | * Click nbfs://nbhost/SystemFileSystem/Templates/Classes/Class.java to edit this template 4 | */ 5 | package basicgraphics.images; 6 | 7 | import java.awt.Dimension; 8 | import java.awt.Graphics; 9 | 10 | /** 11 | * 12 | * @author steve 13 | */ 14 | public interface Painter { 15 | public void paint(Graphics g,Dimension d); 16 | } 17 | -------------------------------------------------------------------------------- /nbproject/genfiles.properties: -------------------------------------------------------------------------------- 1 | # This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml. 2 | # Do not edit this file. You may delete it but then the IDE will never regenerate such files for you. 3 | build.xml.data.CRC32=a0a1bdce 4 | build.xml.script.CRC32=328a4814 5 | build.xml.stylesheet.CRC32=f85dc8f2@1.90.1.48 6 | nbproject/build-impl.xml.data.CRC32=a0a1bdce 7 | nbproject/build-impl.xml.script.CRC32=ecbd0fff 8 | nbproject/build-impl.xml.stylesheet.CRC32=12e0a6c2@1.109.0.48 9 | -------------------------------------------------------------------------------- /src/basicgraphics/PaintRegion.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Click nbfs://nbhost/SystemFileSystem/Templates/Licenses/license-default.txt to change this license 3 | * Click nbfs://nbhost/SystemFileSystem/Templates/Classes/Interface.java to edit this template 4 | */ 5 | package basicgraphics; 6 | 7 | import java.awt.Graphics; 8 | 9 | /** 10 | * 11 | * @author steve 12 | */ 13 | public interface PaintRegion { 14 | public void paintRegion(Graphics g,int sx1,int sy1,int sx2,int sy2,int dx1,int dy1,int dx2,int dy2); 15 | } 16 | -------------------------------------------------------------------------------- /src/prog/game/board.txt: -------------------------------------------------------------------------------- 1 | i = 0 2 | x 3 | i += 1 4 | if i < 1: 5 | x 6 | else: 7 | x 8 | x 9 | x 10 | if d1 < 3: 11 | g 12 | elif d1 < 4: 13 | x 14 | x 15 | if d2 > 1: 16 | x 17 | x 18 | else: 19 | x 20 | else: 21 | x 22 | g 23 | x 24 | if d1 > 4: 25 | x 26 | else: 27 | x 28 | g 29 | x 30 | x 31 | x 32 | if d1 > 2 and d2 <= 5: 33 | g 34 | x 35 | if d1 < 2 or d2 >= 5: 36 | g 37 | x 38 | x 39 | if d1 < 2: 40 | g 41 | elif d2 >= 4: 42 | x 43 | g 44 | while i < d1: 45 | i += 1 46 | i=6 47 | while d2 < i: 48 | i -= 1 49 | x 50 | -------------------------------------------------------------------------------- /src/boardgame/Piece.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this license header, choose License Headers in Project Properties. 3 | * To change this template file, choose Tools | Templates 4 | * and open the template in the editor. 5 | */ 6 | package boardgame; 7 | 8 | /** 9 | * 10 | * @author sbrandt 11 | */ 12 | public abstract class Piece { 13 | int x,y; 14 | static int nextId = 0; 15 | final int id = nextId++; 16 | public int getX() { return x; } 17 | public int getY() { return y; } 18 | public abstract void checkMove(int x1,int x2,int y1,int y2); 19 | } 20 | -------------------------------------------------------------------------------- /src/boardgame/Move.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this license header, choose License Headers in Project Properties. 3 | * To change this template file, choose Tools | Templates 4 | * and open the template in the editor. 5 | */ 6 | package boardgame; 7 | 8 | /** 9 | * 10 | * @author sbrandt 11 | */ 12 | public class Move { 13 | final int pieceId; 14 | final int fromX, fromY, toX, toY; 15 | public Move(int pid,int fx,int fy,int tx,int ty) { 16 | pieceId = pid; 17 | fromX = fx; 18 | fromY = fy; 19 | toX = tx; 20 | toY = ty; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/basicgraphics/GuiException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this license header, choose License Headers in Project Properties. 3 | * To change this template file, choose Tools | Templates 4 | * and open the template in the editor. 5 | */ 6 | package basicgraphics; 7 | 8 | /** 9 | * 10 | * @author sbrandt 11 | */ 12 | public class GuiException extends RuntimeException { 13 | 14 | public GuiException() { 15 | } 16 | 17 | public GuiException(String str) { 18 | super(str); 19 | } 20 | 21 | public GuiException(Exception ex) { 22 | super(ex); 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /src/basicgraphics/examples/Foo.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Click nbfs://nbhost/SystemFileSystem/Templates/Licenses/license-default.txt to change this license 3 | * Click nbfs://nbhost/SystemFileSystem/Templates/Classes/Class.java to edit this template 4 | */ 5 | package basicgraphics.examples; 6 | 7 | import java.awt.event.ActionEvent; 8 | import java.awt.event.ActionListener; 9 | 10 | /** 11 | * 12 | * @author steve 13 | */ 14 | 15 | 16 | public class Foo implements ActionListener { 17 | 18 | @Override 19 | public void actionPerformed(ActionEvent ae) { 20 | System.out.println("Click!"); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /nbproject/project.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | org.netbeans.modules.java.j2seproject 4 | 5 | 6 | 7 | BasicGraphics 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /src/basicshooter/Shooter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this license header, choose License Headers in Project Properties. 3 | * To change this template file, choose Tools | Templates 4 | * and open the template in the editor. 5 | */ 6 | package basicshooter; 7 | 8 | import basicgraphics.Scene; 9 | import basicgraphics.Sprite; 10 | import basicgraphics.SpriteComponent; 11 | 12 | /** 13 | * 14 | * @author sbrandt 15 | */ 16 | public class Shooter extends Sprite { 17 | public Shooter(Scene sc) { 18 | super(sc); 19 | setPicture(Game.makeBall(Game.SHOOTER_COLOR, Game.BIG)); 20 | setX(Game.BOARD_SIZE.width/2); 21 | setY(Game.BOARD_SIZE.height/2); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/prog/game/prog.peg: -------------------------------------------------------------------------------- 1 | # PEG File 2 | skipper = (\b[ \t]*|[ \t]+) 3 | 4 | name = [a-zA-Z][a-zA-Z0-9_]* 5 | float = -?[0-9]+\.[0-9]+ 6 | num = -?[0-9]+ 7 | addop = [+-] 8 | mulop = [*/%] 9 | factor = {name}|{float}|{num}|\( {expr} \) 10 | addend = {-factor}( {mulop} {-factor})* 11 | expr = {addend}( {addop} {addend})* 12 | condop = ([<>]=?|==|!=) 13 | cond2 = {expr} {condop} {expr} 14 | cond1 = not {expr} 15 | cond = (\( {condexpr} \)|{cond1}|{cond2}) 16 | andor = (and|or) 17 | condexpr = {-cond}( {andor} {-cond})? 18 | iew = (if|elif|while) 19 | aop = (\+=|-=|=) 20 | assign = {name} {aop} {expr} 21 | s = [ \t]* 22 | x = x 23 | g = g 24 | else = else 25 | line = ^{s}({iew} {condexpr} :|{else}:|{x}|{g}|{assign}).*$ -------------------------------------------------------------------------------- /src/basicgraphics/Card.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Click nbfs://nbhost/SystemFileSystem/Templates/Licenses/license-default.txt to change this license 3 | * Click nbfs://nbhost/SystemFileSystem/Templates/Classes/Class.java to edit this template 4 | */ 5 | package basicgraphics; 6 | 7 | import basicgraphics.images.Picture; 8 | import java.awt.Dimension; 9 | import java.awt.Graphics; 10 | 11 | /** 12 | * 13 | * @author steve 14 | */ 15 | public class Card extends BasicContainer { 16 | 17 | final String cardName; 18 | public Card(String name) { 19 | cardName = name; 20 | } 21 | 22 | public void showCard() { 23 | BasicFrame.cards.show(getParent(), cardName); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/basicgraphics/images/RuntimeIOException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this license header, choose License Headers in Project Properties. 3 | * To change this template file, choose Tools | Templates 4 | * and open the template in the editor. 5 | */ 6 | package basicgraphics.images; 7 | 8 | import java.io.IOException; 9 | 10 | /** 11 | * Protect users from needing to catch IOException 12 | * @author sbrandt 13 | */ 14 | public class RuntimeIOException extends RuntimeException { 15 | public RuntimeIOException(String string,Throwable t) { 16 | super(string,t); 17 | } 18 | 19 | public RuntimeIOException(String string) { 20 | super(string); 21 | } 22 | 23 | RuntimeIOException(IOException ex) { 24 | super(ex); 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /src/boardgame/Game.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this license header, choose License Headers in Project Properties. 3 | * To change this template file, choose Tools | Templates 4 | * and open the template in the editor. 5 | */ 6 | package boardgame; 7 | 8 | import java.util.ArrayList; 9 | import java.util.List; 10 | 11 | /** 12 | * 13 | * @author sbrandt 14 | */ 15 | public class Game implements Runnable { 16 | Board board; 17 | List players = new ArrayList<>(); 18 | int nextPlayer = 0; 19 | 20 | public void run() { 21 | Move move = players.get(nextPlayer).getMove(); 22 | if(move == null) { 23 | nextPlayer = (nextPlayer + 1) % players.size(); 24 | return; 25 | } 26 | board.move(move); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/basicgraphics/Bounds.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this license header, choose License Headers in Project Properties. 3 | * To change this template file, choose Tools | Templates 4 | * and open the template in the editor. 5 | */ 6 | package basicgraphics; 7 | 8 | /** 9 | * 10 | * @author sbrandt 11 | */ 12 | public class Bounds { 13 | final public int left, right, above, below, width, height; 14 | public String toString() { 15 | return "{"+left+","+right+","+above+","+below+"}"; 16 | } 17 | public Bounds(int left,int right,int above,int below) { 18 | this.left = left; 19 | this.right = right; 20 | this.above = above; 21 | this.below = below; 22 | this.width = left + right; 23 | this.height = above + below; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/maze/Cell.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this license header, choose License Headers in Project Properties. 3 | * To change this template file, choose Tools | Templates 4 | * and open the template in the editor. 5 | */ 6 | package maze; 7 | 8 | /** 9 | * The cell class represents one square on the maze game board. 10 | * 11 | * @author sbrandt 12 | */ 13 | class Cell { 14 | 15 | /** 16 | * If the sequence is greater than zero, it means the maze was visited by 17 | * the PathFinder interface while searching the shortest path. 18 | */ 19 | int sequence = 0; 20 | boolean isWall = true; 21 | /** 22 | * The starting position in the maze. 23 | */ 24 | boolean isStart = false; 25 | /** 26 | * The end or goal of the maze. 27 | */ 28 | boolean isGoal = false; 29 | 30 | boolean canSearch() { 31 | return sequence == 0 && !isWall; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/basicgraphics/BadComponent.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this license header, choose License Headers in Project Properties. 3 | * To change this template file, choose Tools | Templates 4 | * and open the template in the editor. 5 | */ 6 | package basicgraphics; 7 | 8 | import java.awt.Color; 9 | import java.awt.Component; 10 | import java.awt.Dimension; 11 | import java.awt.Graphics; 12 | 13 | /** 14 | * 15 | * @author sbrandt 16 | */ 17 | class BadComponent extends Component { 18 | 19 | public BadComponent() { 20 | } 21 | 22 | @Override 23 | public void paint(Graphics g) { 24 | Dimension d = getSize(); 25 | g.setColor(Color.red); 26 | g.fillRect(0, 0, d.width, d.height); 27 | g.setColor(Color.black); 28 | g.drawRect(0, 0, d.width, d.height); 29 | g.drawLine(0,0, d.width, d.height); 30 | g.drawLine(0, d.height, d.width, 0); 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /src/basicgraphics/ErrorComponent.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this license header, choose License Headers in Project Properties. 3 | * To change this template file, choose Tools | Templates 4 | * and open the template in the editor. 5 | */ 6 | package basicgraphics; 7 | 8 | import java.awt.Color; 9 | import java.awt.Dimension; 10 | import java.awt.Graphics; 11 | import javax.swing.JComponent; 12 | 13 | /** 14 | * This component is displayed in regions 15 | * of the frame where the programmer has 16 | * not supplied anything to display. 17 | * @author sbrandt 18 | */ 19 | class ErrorComponent extends JComponent{ 20 | @Override 21 | public void paintComponent(Graphics g) { 22 | Dimension d = getSize(); 23 | g.setColor(Color.red); 24 | g.fillRect(0, 0, d.width, d.height); 25 | g.setColor(Color.black); 26 | g.drawRect(0, 0, d.width, d.height); 27 | g.drawLine(0,0,d.width,d.height); 28 | g.drawLine(d.width, 0, 0, d.height); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/maze/Pos.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this license header, choose License Headers in Project Properties. 3 | * To change this template file, choose Tools | Templates 4 | * and open the template in the editor. 5 | */ 6 | package maze; 7 | 8 | /** 9 | * Represents a position (x and y coordinate) on the game board used 10 | * by the Maze class. One can find a given cell on the board by typing: 11 | * 12 | *
13 |  * Cell c = maze.board[p.x][p.y];
14 |  * 
15 | * 16 | * @author sbrandt 17 | */ 18 | class Pos { 19 | int x, y; 20 | Pos(int _x, int _y) { 21 | x=_x; 22 | y=_y; 23 | } 24 | @Override 25 | public boolean equals(Object o) { 26 | Pos that = (Pos)o; 27 | if(that == null) return false; 28 | return this.x == that.x && this.y == that.y; 29 | } 30 | public Pos add(Pos that) { 31 | return new Pos(this.x + that.x, this.y + that.y); 32 | } 33 | public String toString() { 34 | return "("+x+","+y+")"; 35 | } 36 | } 37 | 38 | -------------------------------------------------------------------------------- /src/basicgraphics/images/BackgroundPainter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Click nbfs://nbhost/SystemFileSystem/Templates/Licenses/license-default.txt to change this license 3 | * Click nbfs://nbhost/SystemFileSystem/Templates/Classes/Class.java to edit this template 4 | */ 5 | package basicgraphics.images; 6 | 7 | import basicgraphics.images.Picture; 8 | import java.awt.Dimension; 9 | import java.awt.Graphics; 10 | 11 | /** 12 | * 13 | * @author steve 14 | */ 15 | public class BackgroundPainter implements Painter { 16 | 17 | public final Picture background; 18 | 19 | public BackgroundPainter(Picture p) { 20 | background = p; 21 | } 22 | 23 | @Override 24 | public void paint(Graphics g, Dimension d) { 25 | double scalex = background.getWidth() * 1.0 / d.width; 26 | double scaley = background.getHeight() * 1.0 / d.height; 27 | double scale = scalex < scaley ? scalex : scaley; 28 | double bgx = d.width * scale; 29 | double bgy = d.height * scale; 30 | g.drawImage(background.getImage(), 0, 0, d.width, d.height, 31 | 0, 0, (int) bgx, (int) bgy, null); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/basicgraphics/examples/Bat.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this license header, choose License Headers in Project Properties. 3 | * To change this template file, choose Tools | Templates 4 | * and open the template in the editor. 5 | */ 6 | package basicgraphics.examples; 7 | 8 | import basicgraphics.CollisionEventType; 9 | import basicgraphics.Scene; 10 | import basicgraphics.Sprite; 11 | import basicgraphics.SpriteCollisionEvent; 12 | import basicgraphics.images.Picture; 13 | 14 | /** 15 | * 16 | * @author sbrandt 17 | */ 18 | public class Bat extends Sprite { 19 | 20 | public Bat(Scene sc) { 21 | super(sc); 22 | setPicture(new Picture("bat.png")); 23 | setVel(1, 1); 24 | } 25 | 26 | @Override 27 | public void processEvent(SpriteCollisionEvent ce) { 28 | if (ce.eventType == CollisionEventType.WALL) { 29 | if (ce.xlo) { 30 | setVel(Math.abs(getVelX()), getVelY()); 31 | } 32 | if (ce.xhi) { 33 | setVel(-Math.abs(getVelX()), getVelY()); 34 | } 35 | if (ce.ylo) { 36 | setVel(getVelX(), Math.abs(getVelY())); 37 | } 38 | if (ce.yhi) { 39 | setVel(getVelX(), -Math.abs(getVelY())); 40 | } 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/boardgame/Board.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this license header, choose License Headers in Project Properties. 3 | * To change this template file, choose Tools | Templates 4 | * and open the template in the editor. 5 | */ 6 | package boardgame; 7 | 8 | import java.util.ArrayList; 9 | import java.util.HashMap; 10 | import java.util.Iterator; 11 | import java.util.List; 12 | import java.util.Map; 13 | 14 | /** 15 | * 16 | * @author sbrandt 17 | */ 18 | public class Board { 19 | 20 | private List>> board = new ArrayList<>(); 21 | Map pieceMap = new HashMap<>(); 22 | 23 | public void move(Move m) { 24 | Piece p = pieceMap.get(m.pieceId); 25 | p.checkMove(m.fromX,m.fromY,m.toX,m.toY); 26 | fireMove(m); 27 | } 28 | 29 | private void fireMove(Move m) { 30 | Iterator miter = moveListeners.iterator(); 31 | while(miter.hasNext()) { 32 | try { 33 | miter.next().moveMade(m); 34 | } catch(Exception e) { 35 | e.printStackTrace(System.err); 36 | miter.remove(); 37 | } 38 | } 39 | } 40 | 41 | List moveListeners = new ArrayList<>(); 42 | 43 | public void addMoveListener(MoveListener mv) { 44 | moveListeners.add(mv); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/basicgraphics/SpriteCollisionEvent.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this license header, choose License Headers in Project Properties. 3 | * To change this template file, choose Tools | Templates 4 | * and open the template in the editor. 5 | */ 6 | package basicgraphics; 7 | 8 | /** 9 | * 10 | * @author sbrandt 11 | */ 12 | public class SpriteCollisionEvent { 13 | public final boolean xlo, xhi, ylo, yhi; 14 | public final CollisionEventType eventType; 15 | 16 | public SpriteCollisionEvent(boolean xlo, boolean xhi, boolean ylo, boolean yhi, CollisionEventType ct) { 17 | this.xlo = xlo; 18 | this.xhi = xhi; 19 | this.ylo = ylo; 20 | this.yhi = yhi; 21 | this.eventType = ct; 22 | if (ct == null) { 23 | throw new NullPointerException(); 24 | } 25 | } 26 | private final static String PRE = "CollisionEvent["; 27 | public String toString() { 28 | StringBuilder sb = new StringBuilder(); 29 | sb.append(PRE); 30 | append(sb,"xlo",xlo); 31 | append(sb,"xhi",xhi); 32 | append(sb,"ylo",ylo); 33 | append(sb,"yhi",yhi); 34 | append(sb,eventType.toString(),true); 35 | sb.append(']'); 36 | return sb.toString(); 37 | } 38 | private void append(StringBuilder sb,String s,boolean b) { 39 | if(b) { 40 | if(sb.length()>PRE.length()) 41 | sb.append(','); 42 | sb.append(s); 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/basicgraphics/KeyWrapper.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this license header, choose License Headers in Project Properties. 3 | * To change this template file, choose Tools | Templates 4 | * and open the template in the editor. 5 | */ 6 | package basicgraphics; 7 | 8 | import java.awt.event.KeyEvent; 9 | import java.awt.event.KeyListener; 10 | import javax.swing.JOptionPane; 11 | import javax.swing.SwingUtilities; 12 | 13 | /** 14 | * 15 | * @author sbrandt 16 | */ 17 | public class KeyWrapper implements KeyListener { 18 | 19 | KeyListener kl; 20 | public KeyWrapper(KeyListener kl) { 21 | this.kl = kl; 22 | } 23 | 24 | @Override 25 | public void keyTyped(final KeyEvent e) { 26 | Runnable run = new Runnable() { 27 | public void run() { 28 | kl.keyTyped(e); 29 | } 30 | }; 31 | TaskRunner.runLater(e.getComponent(), run); 32 | } 33 | 34 | @Override 35 | public void keyPressed(final KeyEvent e) { 36 | Runnable run = new Runnable() { 37 | public void run() { 38 | kl.keyPressed(e); 39 | } 40 | }; 41 | TaskRunner.runLater(e.getComponent(), run); 42 | } 43 | 44 | @Override 45 | public void keyReleased(final KeyEvent e) { 46 | Runnable run = new Runnable() { 47 | public void run() { 48 | kl.keyReleased(e); 49 | } 50 | }; 51 | TaskRunner.runLater(e.getComponent(), run); 52 | } 53 | 54 | } 55 | -------------------------------------------------------------------------------- /src/basicshooter/Bullet.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this license header, choose License Headers in Project Properties. 3 | * To change this template file, choose Tools | Templates 4 | * and open the template in the editor. 5 | */ 6 | package basicshooter; 7 | 8 | import basicgraphics.Scene; 9 | import basicgraphics.Sprite; 10 | import basicgraphics.SpriteComponent; 11 | import java.awt.event.KeyEvent; 12 | 13 | /** 14 | * 15 | * @author sbrandt 16 | */ 17 | class Bullet extends Sprite { 18 | Bullet(Scene sc,Sprite sp,int direction) { 19 | super(sc); 20 | setPicture(Game.makeBall(Game.BULLET_COLOR, Game.SMALL)); 21 | setCenterX(sp.centerX()); 22 | setCenterY(sp.centerY()); 23 | if(direction == KeyEvent.VK_DOWN) 24 | setVel(0, 2.0); 25 | else if(direction == KeyEvent.VK_UP) 26 | setVel(0, -2.0); 27 | else if(direction == KeyEvent.VK_RIGHT) 28 | setVel(2.0, 0); 29 | else if(direction == KeyEvent.VK_LEFT) 30 | setVel(-2.0, 0); 31 | } 32 | 33 | Bullet(Scene sc, Shooter sp, int x, int y) { 34 | super(sc); 35 | setPicture(Game.makeBall(Game.BULLET_COLOR, Game.SMALL)); 36 | setX(sp.getX()+(Game.BIG-Game.SMALL)/2); 37 | setY(sp.getY()+(Game.BIG-Game.SMALL)/2); 38 | double delx = x-sp.getX()-sp.getWidth()/2; 39 | double dely = y-sp.getY()-sp.getHeight()/2; 40 | double dist = Math.sqrt(delx*delx+dely*dely); 41 | setVel(2*delx/dist,2*dely/dist); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/robosorter/MartianEgg.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this license header, choose License Headers in Project Properties. 3 | * To change this template file, choose Tools | Templates 4 | * and open the template in the editor. 5 | */ 6 | package robosorter; 7 | 8 | import basicgraphics.BasicFrame; 9 | import basicgraphics.Scene; 10 | import basicgraphics.Sprite; 11 | import basicgraphics.images.Picture; 12 | import java.awt.Color; 13 | import java.awt.Font; 14 | import java.awt.Graphics; 15 | import java.awt.image.BufferedImage; 16 | 17 | /** 18 | * 19 | * @author sbrandt 20 | */ 21 | public class MartianEgg extends Sprite { 22 | final int num; 23 | public MartianEgg(Scene sc,int num) { 24 | super(sc); 25 | this.num = num; 26 | BufferedImage image = BasicFrame.createImage(Robo.BLOCK_SIZE, Robo.BLOCK_SIZE); 27 | Graphics g = image.getGraphics(); 28 | g.setColor(Color.white); 29 | g.fillRect(0, 0, Robo.BLOCK_SIZE, Robo.BLOCK_SIZE); 30 | g.setColor(new Color(0xEE,0xEE,0xFF)); 31 | g.fillOval(0, 0, Robo.BLOCK_SIZE, Robo.BLOCK_SIZE); 32 | g.setColor(Color.BLACK); 33 | g.drawOval(0, 0, Robo.BLOCK_SIZE, Robo.BLOCK_SIZE); 34 | g.setFont(new Font(Font.MONOSPACED, Font.BOLD, Robo.BLOCK_SIZE/2)); 35 | g.drawString(""+num, Robo.BLOCK_SIZE/5, Robo.BLOCK_SIZE*3/4); 36 | setPicture(new Picture(image)); 37 | getPicture().transparentBright(); 38 | } 39 | public String toString() { 40 | return "Egg("+num+")"; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/basicflyer/Plasma.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this license header, choose License Headers in Project Properties. 3 | * To change this template file, choose Tools | Templates 4 | * and open the template in the editor. 5 | */ 6 | package basicflyer; 7 | 8 | import basicgraphics.BasicFrame; 9 | import basicgraphics.Scene; 10 | import basicgraphics.Sprite; 11 | import basicgraphics.SpriteCollisionEvent; 12 | import basicgraphics.SpriteComponent; 13 | import basicgraphics.images.Picture; 14 | import java.awt.Color; 15 | import java.awt.Graphics; 16 | import java.awt.Image; 17 | 18 | /** 19 | * 20 | * @author sbrandt 21 | */ 22 | public class Plasma extends Sprite { 23 | 24 | /** 25 | * Creates a picture of a ball with the given color and size. 26 | * 27 | * @param color 28 | * @param size 29 | * @return 30 | */ 31 | public static Picture makeBall(Color color, int size) { 32 | Image im = BasicFrame.createImage(size, size); 33 | Graphics g = im.getGraphics(); 34 | g.setColor(color); 35 | g.fillOval(0, 0, size, size); 36 | return new Picture(im); 37 | } 38 | 39 | /** 40 | * Just sets the picture. 41 | * 42 | * @param sc 43 | */ 44 | public Plasma(Scene sc) { 45 | super(sc); 46 | setPicture(makeBall(Color.red, Flyer.PLASMA_SIZE)); 47 | } 48 | 49 | /** 50 | * Disappears if it comes in contact with the display boundary. 51 | * 52 | * @param se 53 | */ 54 | @Override 55 | public void processEvent(SpriteCollisionEvent se) { 56 | //setActive(false); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /src/basicgraphics/Task.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this license header, choose License Headers in Project Properties. 3 | * To change this template file, choose Tools | Templates 4 | * and open the template in the editor. 5 | */ 6 | package basicgraphics; 7 | 8 | /** 9 | * 10 | * @author sbrandt 11 | */ 12 | public abstract class Task implements Runnable { 13 | private boolean submitted = false; 14 | int iteration; 15 | private boolean finished = false; 16 | final private int minIter, maxIter; 17 | void setSubmitted() { submitted = true; } 18 | public boolean isSubmitted() { return submitted; } 19 | public int iteration() { return iteration; } 20 | public void setFinished() { finished = true; } 21 | public boolean isFinished() { return finished; } 22 | public int maxIteration() { return maxIter; } 23 | public abstract void run(); 24 | final void run_() { 25 | iteration++; 26 | try { 27 | run(); 28 | } catch(Throwable ex) { 29 | ex.printStackTrace(); 30 | setFinished(); 31 | } 32 | if(iteration == maxIter) { 33 | setFinished(); 34 | } 35 | } 36 | 37 | public Task() { 38 | this.minIter = 0; 39 | this.maxIter = Integer.MAX_VALUE; 40 | this.iteration = this.minIter-1; 41 | } 42 | public Task(int maxIter) { 43 | this.minIter = 0; 44 | this.maxIter = maxIter; 45 | this.iteration = this.minIter-1; 46 | } 47 | public Task(int minIter, int maxIter) { 48 | this.minIter = minIter; 49 | this.maxIter = maxIter; 50 | this.iteration = this.minIter-1; 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/basicgraphics/Util.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Click nbfs://nbhost/SystemFileSystem/Templates/Licenses/license-default.txt to change this license 3 | * Click nbfs://nbhost/SystemFileSystem/Templates/Classes/Class.java to edit this template 4 | */ 5 | package basicgraphics; 6 | 7 | import javax.swing.SwingUtilities; 8 | 9 | /** 10 | * 11 | * @author steve 12 | */ 13 | public class Util { 14 | 15 | /** 16 | * The java == operator does not compare String or Integer 17 | * objects correctly. Instead, one has to use the object's 18 | * equals method to compare them correctly. 19 | * @param a 20 | * @param b 21 | * @return 22 | */ 23 | public static boolean eq(Object a, Object b) { 24 | if(a == b) return true; 25 | if(a == null || b == null) return false; 26 | if(a.getClass().isAssignableFrom(b.getClass())) 27 | return b.equals(a); 28 | else 29 | return a.equals(b); 30 | } 31 | 32 | /** 33 | * This method immediately invokes runnable method r 34 | * on the event dispatch thread. 35 | * @param r 36 | */ 37 | public static void invokeAndWait(Runnable r) { 38 | if(SwingUtilities.isEventDispatchThread()) 39 | r.run(); 40 | else { 41 | try { 42 | SwingUtilities.invokeAndWait(r); 43 | } catch(Exception ex) { 44 | TaskRunner.report(ex, null); 45 | } 46 | } 47 | } 48 | 49 | static void sleep(int duration) { 50 | try { 51 | Thread.sleep(duration); 52 | } catch (InterruptedException ex) { 53 | TaskRunner.report(ex, null); 54 | } 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/basicflyer/Falcon.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this license header, choose License Headers in Project Properties. 3 | * To change this template file, choose Tools | Templates 4 | * and open the template in the editor. 5 | */ 6 | package basicflyer; 7 | 8 | import basicgraphics.Scene; 9 | import basicgraphics.Sprite; 10 | import basicgraphics.SpriteCollisionEvent; 11 | import basicgraphics.SpriteComponent; 12 | import basicgraphics.images.Picture; 13 | import java.awt.Dimension; 14 | 15 | /** 16 | * 17 | * @author sbrandt 18 | */ 19 | public class Falcon extends Sprite { 20 | public Picture initialPic; 21 | public final static double FAC = .9; 22 | /** 23 | * Initializes the sprite, setting its picture, 24 | * position, and speed. It also adds it to the 25 | * SpriteComponent. 26 | * 27 | * @param sc 28 | */ 29 | public Falcon(Scene sc) { 30 | super(sc); 31 | initialPic = new Picture("mfalcon.png"); 32 | setPicture(initialPic); 33 | Dimension d = sc.getSize(); 34 | setX(d.width/2); 35 | setY(d.height/2); 36 | setVel(FAC, 0); 37 | } 38 | 39 | /** 40 | * This sprite only reacts to collisions with the 41 | * borders of the display region. When it does, it 42 | * wraps to the other side. 43 | * @param se 44 | */ 45 | @Override 46 | public void processEvent(SpriteCollisionEvent se) { 47 | SpriteComponent sc = getSpriteComponent(); 48 | if (se.xlo) { 49 | setX(sc.getFullSize().width-getWidth()); 50 | } 51 | if (se.xhi) { 52 | setX(0); 53 | } 54 | if (se.ylo) { 55 | setY(sc.getFullSize().height-getHeight()); 56 | } 57 | if (se.yhi) { 58 | setY(0); 59 | } 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/robosorter/Robo.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this license header, choose License Headers in Project Properties. 3 | * To change this template file, choose Tools | Templates 4 | * and open the template in the editor. 5 | */ 6 | package robosorter; 7 | 8 | import basicgraphics.BasicFrame; 9 | import basicgraphics.ClockWorker; 10 | import basicgraphics.SpriteComponent; 11 | import java.awt.Dimension; 12 | import java.awt.Graphics; 13 | import java.util.Random; 14 | 15 | /** 16 | * 17 | * @author sbrandt 18 | */ 19 | public class Robo { 20 | static String[][] layout = { 21 | {"one"} 22 | }; 23 | final static int NX = 10, NY = 3, BLOCK_SIZE = 50, PADDING=3, SPEED = 5; 24 | public final static Random RAND = new Random(); 25 | 26 | public static void main(String[] args) { 27 | BasicFrame bf = new BasicFrame("Robo"); 28 | SpriteComponent sc = new SpriteComponent() { 29 | @Override 30 | public void paintBackground(Graphics g) { 31 | Dimension d = getSize(); 32 | g.clearRect(0,0,d.width,d.height); 33 | for(int i=0;i actions = new LinkedList<>(); 25 | 26 | public Mover(Scene sc, Board board) { 27 | super(sc); 28 | Picture p = new Picture("claw.png").transparentBright(); 29 | this.board = board; 30 | setPicture(p); 31 | ClockWorker.addTask(new Task() { 32 | @Override 33 | public void run() { 34 | doMove(); 35 | } 36 | }); 37 | } 38 | 39 | Runnable running = null; 40 | 41 | public void doMove() { 42 | if (count > 0) { 43 | count--; 44 | if (count == 0) { 45 | setVel(0,0); 46 | } 47 | } 48 | if (count == 0 || running == null) { 49 | if (!actions.isEmpty()) { 50 | Runnable r = actions.removeFirst(); 51 | running = r; 52 | try { 53 | r.run(); 54 | } catch (Exception e) { 55 | e.printStackTrace(System.err); 56 | System.exit(0); 57 | } 58 | } 59 | } 60 | if (carrying != null) { 61 | carrying.setX(getX()); 62 | carrying.setY(getY()); 63 | } 64 | } 65 | 66 | public String toString() { 67 | return "Mover"; 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /src/langtonsant/AntSprite.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this license header, choose License Headers in Project Properties. 3 | * To change this template file, choose Tools | Templates 4 | * and open the template in the editor. 5 | */ 6 | package langtonsant; 7 | 8 | import basicgraphics.ClockWorker; 9 | import basicgraphics.Scene; 10 | import basicgraphics.Sprite; 11 | import basicgraphics.SpriteComponent; 12 | import basicgraphics.Task; 13 | import basicgraphics.images.Picture; 14 | import java.awt.Dimension; 15 | 16 | /** 17 | * 18 | * @author sbrandt 19 | */ 20 | class AntSprite extends Sprite { 21 | Picture pic; 22 | 23 | public AntSprite(Scene sc,boolean[][] grid) { 24 | super(sc); 25 | pic = new Picture("ant-small.png"); 26 | setPicture(pic); 27 | this.grid = grid; 28 | ClockWorker.addTask(new Task() { 29 | @Override 30 | public void run() { 31 | doMove(); 32 | } 33 | }); 34 | } 35 | 36 | int i=Ant.NX/2,j=Ant.NY/2; 37 | int facing = 2; 38 | boolean[][] grid; 39 | 40 | public void doMove() { 41 | SpriteComponent sc = getSpriteComponent(); 42 | Dimension d = sc.getSize(); 43 | int delx = d.width / Ant.NX; 44 | int dely = d.height / Ant.NY; 45 | setX(i * delx + (delx - getPicture().getWidth())/2); 46 | setY(j * dely + (dely - getPicture().getHeight())/2); 47 | if(grid[i][j]) { 48 | facing += 1; 49 | } else { 50 | facing -= 1; 51 | } 52 | rotate(Math.PI*0.5*facing); 53 | grid[i][j] = !grid[i][j]; 54 | int facingx = (int)Math.round(Math.cos(Math.PI*facing/2)); 55 | int facingy = (int)Math.round(Math.sin(Math.PI*facing/2)); 56 | 57 | i += facingx; 58 | j += facingy; 59 | if(j < 0) j += Ant.NY; 60 | if(i < 0) i += Ant.NX; 61 | if(j >= Ant.NY) j -= Ant.NY; 62 | if(i >= Ant.NX) i -= Ant.NX; 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /src/basicgraphics/Scene.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Click nbfs://nbhost/SystemFileSystem/Templates/Licenses/license-default.txt to change this license 3 | * Click nbfs://nbhost/SystemFileSystem/Templates/Classes/Class.java to edit this template 4 | */ 5 | package basicgraphics; 6 | 7 | import basicgraphics.images.Painter; 8 | import basicgraphics.images.Picture; 9 | import java.awt.Dimension; 10 | import java.awt.image.BufferedImage; 11 | import java.util.Set; 12 | import java.util.TreeSet; 13 | 14 | /** 15 | * 16 | * @author steve 17 | */ 18 | public class Scene { 19 | SpriteComponent spritecomponent; 20 | final Set sprites = new TreeSet<>(); 21 | Picture background; 22 | Dimension backgroundSize; 23 | Sprite focus = null; 24 | int offsetX=0, offsetY=0; 25 | 26 | public boolean periodic_x = false; 27 | public boolean periodic_y = false; 28 | 29 | void addSprite(Sprite sp) { 30 | Util.invokeAndWait(()->{ sprites.add(sp);}); 31 | } 32 | 33 | Scene(SpriteComponent sc) { 34 | spritecomponent = sc; 35 | } 36 | public void setFocus(Sprite s) { 37 | focus = s; 38 | } 39 | 40 | public void setBackgroundSize(Dimension d) { 41 | backgroundSize = d; 42 | if(background == null) { 43 | BufferedImage bimage = BasicFrame.createImage(d.width, d.height); 44 | spritecomponent.paintBackground(bimage.getGraphics()); 45 | background = new Picture(bimage); 46 | System.out.println("Image size: "+d); 47 | } 48 | } 49 | 50 | Painter painter = null; 51 | public void setPainter(Painter p) { 52 | painter = p; 53 | } 54 | public Painter getPainter() { 55 | return painter; 56 | } 57 | 58 | public Dimension getSize() { 59 | return spritecomponent.getSize(); 60 | } 61 | 62 | public SpriteComponent getSpriteComponent() { 63 | return spritecomponent; 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /src/basicgraphics/MouseWrapper.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this license header, choose License Headers in Project Properties. 3 | * To change this template file, choose Tools | Templates 4 | * and open the template in the editor. 5 | */ 6 | package basicgraphics; 7 | 8 | import java.awt.event.MouseEvent; 9 | import java.awt.event.MouseListener; 10 | 11 | /** 12 | * 13 | * @author sbrandt 14 | */ 15 | public class MouseWrapper implements MouseListener { 16 | 17 | MouseListener ml; 18 | public MouseWrapper(MouseListener ml) { 19 | this.ml = ml; 20 | } 21 | 22 | @Override 23 | public void mouseClicked(final MouseEvent e) { 24 | Runnable run = new Runnable() { 25 | public void run() { 26 | ml.mouseClicked(e); 27 | } 28 | }; 29 | TaskRunner.runLater(e.getComponent(), run); 30 | } 31 | 32 | @Override 33 | public void mousePressed(final MouseEvent e) { 34 | Runnable run = new Runnable() { 35 | public void run() { 36 | ml.mousePressed(e); 37 | } 38 | }; 39 | TaskRunner.runLater(e.getComponent(), run); 40 | } 41 | 42 | @Override 43 | public void mouseReleased(final MouseEvent e) { 44 | Runnable run = new Runnable() { 45 | public void run() { 46 | ml.mouseReleased(e); 47 | } 48 | }; 49 | TaskRunner.runLater(e.getComponent(), run); 50 | } 51 | 52 | @Override 53 | public void mouseEntered(final MouseEvent e) { 54 | Runnable run = new Runnable() { 55 | public void run() { 56 | ml.mouseEntered(e); 57 | } 58 | }; 59 | TaskRunner.runLater(e.getComponent(), run); 60 | } 61 | 62 | @Override 63 | public void mouseExited(final MouseEvent e) { 64 | Runnable run = new Runnable() { 65 | public void run() { 66 | ml.mouseExited(e); 67 | } 68 | }; 69 | TaskRunner.runLater(e.getComponent(), run); 70 | } 71 | 72 | } 73 | -------------------------------------------------------------------------------- /src/langtonsant/Ant.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this license header, choose License Headers in Project Properties. 3 | * To change this template file, choose Tools | Templates 4 | * and open the template in the editor. 5 | */ 6 | package langtonsant; 7 | 8 | import basicgraphics.BasicFrame; 9 | import basicgraphics.ClockWorker; 10 | import basicgraphics.SpriteComponent; 11 | import java.awt.Color; 12 | import java.awt.Dimension; 13 | import java.awt.Graphics; 14 | 15 | /** 16 | * 17 | * @author sbrandt 18 | */ 19 | public class Ant { 20 | public static String[][] layout = new String[][]{ 21 | new String[]{"C"} 22 | }; 23 | int delx, dely; 24 | boolean[][] grid = new boolean[NX][NY]; 25 | final static int NX = 100, NY = 40, PIXELS_X = 1400, PIXELS_Y = 800, SPEED = 50; 26 | public static void main(String[] args) { 27 | Ant ant = new Ant(); 28 | } 29 | public Ant() { 30 | BasicFrame bf = new BasicFrame("Langton's Ant"); 31 | SpriteComponent sc = new SpriteComponent() { 32 | @Override 33 | public void paintBackground(Graphics g) { 34 | Dimension d = getSize(); 35 | g.setColor(Color.white); 36 | g.fillRect(0, 0, d.width, d.height); 37 | g.setColor(Color.green); 38 | delx = d.width/NX; 39 | dely = d.height/NY; 40 | for(int i=0;i newTasks = new ConcurrentLinkedDeque<>(); 21 | private final static Task SENTINAL = new Task() { 22 | @Override 23 | public void run() { 24 | } 25 | }; 26 | 27 | public static void addTask(Task task) { 28 | if (task.isSubmitted()) { 29 | return; 30 | } 31 | task.setSubmitted(); 32 | newTasks.add(task); 33 | } 34 | 35 | public static void finish() { 36 | t.cancel(); 37 | t = null; 38 | } 39 | 40 | public static void initialize(int period) { 41 | if (t != null) { 42 | // throw new GuiException("SpriteComponent already started"); 43 | t.cancel(); 44 | } 45 | t = new Timer(); 46 | TimerTask tt = new TimerTask() { 47 | int toc = 0; 48 | 49 | @Override 50 | public void run() { 51 | newTasks.add(SENTINAL); 52 | while (true) { 53 | final Task task = newTasks.remove(); 54 | if (task == SENTINAL) { 55 | return; 56 | } 57 | Util.invokeAndWait(()->{ task.run_(); }); 58 | if (!task.isFinished()) { 59 | newTasks.add(task); 60 | } 61 | if (t == null) { 62 | break; 63 | } 64 | } 65 | } 66 | }; 67 | t.schedule(tt, 0, period); 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /src/lightsout/LightsOutGame.java: -------------------------------------------------------------------------------- 1 | package lightsout; 2 | 3 | import basicgraphics.BasicFrame; 4 | import basicgraphics.ClockWorker; 5 | import basicgraphics.SpriteComponent; 6 | 7 | import javax.swing.*; 8 | import java.awt.*; 9 | import java.util.Random; 10 | 11 | /** 12 | * @author Max Morris 13 | */ 14 | public class LightsOutGame { 15 | public static final int TILE_SIZE = 75; 16 | public static final int N_TILES = 3; 17 | public static final int PROBLEM_STEPS = 10; 18 | public static final Dimension WINDOW_SIZE = new Dimension(TILE_SIZE * N_TILES,TILE_SIZE * N_TILES); 19 | 20 | private SpriteComponent sc; 21 | private final BasicFrame frame = new BasicFrame("Lights Out"); 22 | 23 | Tile[][] tiles; 24 | int litTiles = 0; 25 | 26 | public void run() { 27 | sc = new SpriteComponent(); 28 | sc.setPreferredSize(WINDOW_SIZE); 29 | frame.createSingletonLayout(sc); 30 | 31 | tiles = new Tile[N_TILES][N_TILES]; 32 | for (int i = 0; i < N_TILES; i++) { 33 | tiles[i] = new Tile[N_TILES]; 34 | for (int j = 0; j < N_TILES; j++) { 35 | tiles[i][j] = new Tile(sc.getScene(), this, j, i, false); 36 | } 37 | } 38 | 39 | generateProblem(); 40 | 41 | frame.show(); 42 | ClockWorker.initialize(1); 43 | ClockWorker.addTask(sc.moveSprites()); 44 | } 45 | 46 | // Generating the board with a sequence of toggleWithNeighbors guarantees the board is solvable 47 | public void generateProblem() { 48 | var rand = new Random(); 49 | for (int i = 0; i < PROBLEM_STEPS; i++) { 50 | var tile = tiles[rand.nextInt(N_TILES)][rand.nextInt(N_TILES)]; 51 | tile.toggleWithNeighbors(false); 52 | } 53 | } 54 | 55 | public void checkWin() { 56 | if (litTiles == 0) { 57 | JOptionPane.showMessageDialog(sc, "You won!"); 58 | System.exit(0); 59 | } 60 | } 61 | 62 | public static void main(String[] args) { 63 | var game = new LightsOutGame(); 64 | game.run(); 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /src/maze/MazePathFinder.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this license header, choose License Headers in Project Properties. 3 | * To change this template file, choose Tools | Templates 4 | * and open the template in the editor. 5 | */ 6 | package maze; 7 | 8 | import java.util.Queue; 9 | import java.util.Stack; 10 | 11 | /** 12 | * 13 | * @author sbrandt 14 | */ 15 | class MazePathFinder implements PathFinder { 16 | boolean addOne(Pos p,int x,int y,Cell[][] m,Queue q,int seq) { 17 | Pos p2 = new Pos(p.x+x,p.y+y); 18 | Cell c = m[p2.x][p2.y]; 19 | if(c.isWall) return false; 20 | if(c.sequence > 0) return false; 21 | c.sequence = seq+1; 22 | q.add(p2); 23 | return true; 24 | } 25 | boolean done = false; 26 | public boolean addPathElement(Pos p,Cell[][] m,Queue q) { 27 | Cell c = m[p.x][p.y]; 28 | if(c.isGoal || done) { 29 | done = true; 30 | return false; 31 | } 32 | int s = c.sequence; 33 | int n = q.size(); 34 | addOne(p, 0, 1,m,q,s); 35 | addOne(p, 0,-1,m,q,s); 36 | addOne(p, 1, 0,m,q,s); 37 | addOne(p,-1, 0,m,q,s); 38 | return q.size() > n; 39 | } 40 | public boolean tracePath(Cell[][] m,Queue q) { 41 | if(q.isEmpty()) 42 | return false; 43 | Pos p = q.remove(); 44 | addPathElement(p,m,q); 45 | return true; 46 | } 47 | boolean retracePath(Pos p,int x,int y,Cell[][] m,Stack s,int seq) { 48 | Pos p2 = new Pos(p.x+x,p.y+y); 49 | Cell c = m[p2.x][p2.y]; 50 | if(c.isWall) return false; 51 | if(c.sequence == seq) { 52 | retracePath(p2,m,s); 53 | return true; 54 | } 55 | return false; 56 | } 57 | public void retracePath(Pos p,Cell[][] m,Stack s) { 58 | Cell c = m[p.x][p.y]; 59 | int seq = c.sequence - 1; 60 | s.push(p); 61 | if(seq == 0) { 62 | return; 63 | } 64 | if(retracePath(p, 0, 1,m,s,seq)) 65 | return; 66 | else if(retracePath(p, 0,-1,m,s,seq)) 67 | return; 68 | else if(retracePath(p, 1, 0,m,s,seq)) 69 | return; 70 | else if(retracePath(p,-1, 0,m,s,seq)) 71 | return; 72 | } 73 | } 74 | 75 | -------------------------------------------------------------------------------- /src/prog/game/ProgSpriteComponent.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this license header, choose License Headers in Project Properties. 3 | * To change this template file, choose Tools | Templates 4 | * and open the template in the editor. 5 | */ 6 | package prog.game; 7 | 8 | import basicgraphics.Sprite; 9 | import basicgraphics.SpriteComponent; 10 | import basicgraphics.images.Picture; 11 | import java.awt.Dimension; 12 | import java.awt.Font; 13 | import java.awt.Graphics; 14 | import java.awt.Image; 15 | import java.awt.image.BufferedImage; 16 | import java.util.List; 17 | import javax.swing.JButton; 18 | import static prog.game.Game.board; 19 | 20 | /** 21 | * 22 | * @author sbrandt 23 | */ 24 | public class ProgSpriteComponent extends SpriteComponent { 25 | 26 | Picture bground; 27 | BufferedImage[] board; 28 | List positions; 29 | List tokens; 30 | JButton viz; 31 | 32 | public ProgSpriteComponent(Picture bground,BufferedImage[] board, 33 | List positions, List tokens, 34 | JButton viz) { 35 | this.bground = bground; 36 | this.board = board; 37 | this.positions = positions; 38 | this.tokens = tokens; 39 | this.viz = viz; 40 | } 41 | 42 | @Override 43 | public void paintBackground(Graphics g) { 44 | Dimension d = getSize(); 45 | g.clearRect(0, 0, d.width, d.height); 46 | g.drawImage(bground.getImage(), 0, 0, this); 47 | g.drawImage(board[0], getOffsetX(), getOffsetY(), null); 48 | g.setFont(new Font(Font.MONOSPACED, Font.BOLD, Game.BOX * 9 / 10)); 49 | int n = 1; 50 | for (Game.Position pos : positions) { 51 | Sprite sp = tokens.get(n - 1); 52 | sp.setY(pos.y * Game.BOX); 53 | sp.setX(pos.x * Game.BOX); 54 | sp.is_visible = true;//"On".equals(viz.getText()); 55 | n++; 56 | } 57 | while (n <= 6) { 58 | Sprite sp = tokens.get(n - 1); 59 | sp.setX(20 * Game.BOX); 60 | sp.is_visible = false; 61 | n++; 62 | } 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /src/basicshooter/Enemy.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this license header, choose License Headers in Project Properties. 3 | * To change this template file, choose Tools | Templates 4 | * and open the template in the editor. 5 | */ 6 | package basicshooter; 7 | 8 | import basicgraphics.CollisionEventType; 9 | import basicgraphics.Scene; 10 | import basicgraphics.Sprite; 11 | import basicgraphics.SpriteCollisionEvent; 12 | import basicgraphics.SpriteComponent; 13 | import basicgraphics.sounds.ReusableClip; 14 | 15 | /** 16 | * 17 | * @author sbrandt 18 | */ 19 | public class Enemy extends Sprite { 20 | static int enemyCount; 21 | 22 | public Enemy(Scene sc) { 23 | super(sc); 24 | enemyCount++; 25 | setPicture(Game.makeBall(Game.ENEMY_COLOR, Game.BIG)); 26 | while (true) { 27 | setX(Game.RAND.nextInt(Game.BOARD_SIZE.width)-Game.SMALL); 28 | setY(Game.RAND.nextInt(Game.BOARD_SIZE.height)-Game.SMALL); 29 | if (Math.abs(getX() - Game.BOARD_SIZE.width / 2) < 2 * Game.BIG 30 | && Math.abs(getY() - Game.BOARD_SIZE.height / 2) < 2 * Game.BIG) { 31 | // Overlaps with center, try again 32 | } else { 33 | break; 34 | } 35 | } 36 | // A random speed 37 | setVel(2 * Game.RAND.nextDouble() - 1, 2 * Game.RAND.nextDouble()); 38 | } 39 | 40 | final static ReusableClip clip = new ReusableClip("die.wav"); 41 | 42 | @Override 43 | public void processEvent(SpriteCollisionEvent se) { 44 | SpriteComponent sc = getSpriteComponent(); 45 | if(se.eventType == CollisionEventType.WALL_INVISIBLE) { 46 | if (se.xlo) { 47 | setX(sc.getSize().width - getWidth()); 48 | } 49 | if (se.xhi) { 50 | setX(0); 51 | } 52 | if (se.ylo) { 53 | setY(sc.getSize().height - getHeight()); 54 | } 55 | if (se.yhi) { 56 | setY(0); 57 | } 58 | } 59 | 60 | // if (se.eventType == CollisionEventType.SPRITE) { 61 | // } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/lightsout/Tile.java: -------------------------------------------------------------------------------- 1 | package lightsout; 2 | 3 | import basicgraphics.BasicFrame; 4 | import basicgraphics.Scene; 5 | import basicgraphics.Sprite; 6 | import basicgraphics.SpriteComponent; 7 | import basicgraphics.images.Picture; 8 | 9 | import java.awt.*; 10 | import java.awt.event.MouseEvent; 11 | 12 | import static lightsout.LightsOutGame.N_TILES; 13 | import static lightsout.LightsOutGame.TILE_SIZE; 14 | 15 | /** 16 | * @author Max Morris 17 | */ 18 | public class Tile extends Sprite { 19 | public boolean lit; 20 | public final int x, y; 21 | private final LightsOutGame gameInstance; 22 | 23 | public Tile(Scene sc, LightsOutGame gameInstance, int x, int y, boolean startLit) { 24 | super(sc); 25 | this.lit = startLit; 26 | this.gameInstance = gameInstance; 27 | this.x = x; 28 | this.y = y; 29 | 30 | setPicture(makeTile(lit)); 31 | setX(x * TILE_SIZE); 32 | setY(y * TILE_SIZE); 33 | } 34 | 35 | public void toggle() { 36 | lit = !lit; 37 | gameInstance.litTiles += lit ? 1 : -1; 38 | setPicture(makeTile(lit)); 39 | } 40 | 41 | public void toggleWithNeighbors(boolean checkWin) { 42 | toggle(); 43 | tryToggle(x - 1, y); 44 | tryToggle(x + 1, y); 45 | tryToggle(x, y - 1); 46 | tryToggle(x, y + 1); 47 | if (checkWin) { 48 | gameInstance.checkWin(); 49 | } 50 | } 51 | 52 | private void tryToggle(int x, int y) { 53 | if (x >= 0 && x < N_TILES && y >= 0 && y < N_TILES) { 54 | gameInstance.tiles[y][x].toggle(); 55 | } 56 | } 57 | 58 | @Override 59 | public void mousePressed(MouseEvent e) { 60 | toggleWithNeighbors(true); 61 | } 62 | 63 | private static Picture makeTile(boolean lit) { 64 | Image im = BasicFrame.createImage(TILE_SIZE, TILE_SIZE); 65 | Graphics g = im.getGraphics(); 66 | 67 | g.setColor(Color.RED); 68 | g.fillRect(0, 0, TILE_SIZE, TILE_SIZE); 69 | 70 | g.setColor(lit ? Color.WHITE : Color.BLACK); 71 | g.fillRect(1, 1, TILE_SIZE - 2, TILE_SIZE - 2); 72 | return new Picture(im); 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /nbproject/project.properties: -------------------------------------------------------------------------------- 1 | annotation.processing.enabled=true 2 | annotation.processing.enabled.in.editor=false 3 | annotation.processing.processors.list= 4 | annotation.processing.run.all.processors=true 5 | application.title=BasicGraphics 6 | application.vendor=sbrandt 7 | build.generated.sources.dir=${build.dir}/generated-sources 8 | debug.modulepath=\ 9 | ${run.modulepath} 10 | debug.test.modulepath=\ 11 | ${run.test.modulepath} 12 | endorsed.classpath= 13 | excludes= 14 | file.reference.build-classes=build/classes 15 | file.reference.piraha.jar=piraha.jar 16 | includes=** 17 | jar.compress=false 18 | javac.classpath=\ 19 | ${file.reference.piraha.jar} 20 | javac.compilerargs=-Xlint:deprecation 21 | javac.deprecation=false 22 | javac.external.vm=false 23 | javac.modulepath= 24 | javac.processormodulepath= 25 | javac.processorpath=\ 26 | ${javac.classpath} 27 | javac.source=18 28 | javac.target=18 29 | javac.test.classpath=\ 30 | ${file.reference.piraha.jar}:\ 31 | ${file.reference.build-classes}:\ 32 | ${build.classes.dir} 33 | javac.test.modulepath=\ 34 | ${javac.modulepath} 35 | javadoc.author=false 36 | javadoc.html5=false 37 | javadoc.noindex=false 38 | javadoc.nonavbar=false 39 | javadoc.notree=false 40 | javadoc.private=false 41 | javadoc.splitindex=false 42 | javadoc.use=false 43 | javadoc.version=false 44 | jlink.launcher=false 45 | jlink.launcher.name=BasicGraphics 46 | main.class=basicflyer.Flyer 47 | mkdist.disabled=false 48 | platform.active=default_platform 49 | run.classpath=\ 50 | ${file.reference.piraha.jar}:\ 51 | ${file.reference.build-classes} 52 | run.jvmargs=-ea 53 | run.modulepath=\ 54 | ${javac.modulepath} 55 | run.test.classpath=\ 56 | ${build.test.classes.dir} 57 | run.test.modulepath=\ 58 | ${javac.test.modulepath} 59 | src.src.dir=src 60 | test.test.dir=test 61 | build.dir=build 62 | dist.dir=dist 63 | build.classes.dir=${build.dir}/classes 64 | dist.javadoc.dir=${dist.dir}/javadoc 65 | build.test.classes.dir=${build.dir}/test/classes 66 | build.test.results.dir=${build.dir}/test/results 67 | build.classes.excludes=**/*.java,**/*.form 68 | dist.jar=${dist.dir}/BasicGraphics.jar 69 | -------------------------------------------------------------------------------- /src/trees/BTree.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this license header, choose License Headers in Project Properties. 3 | * To change this template file, choose Tools | Templates 4 | * and open the template in the editor. 5 | */ 6 | package trees; 7 | 8 | class Node { 9 | char c; 10 | Node left, right; 11 | 12 | Node(char c) { 13 | this.c = c; 14 | } 15 | 16 | void add(char c,StringBuilder sb) { 17 | sb.append(this+" "); 18 | if(c > this.c) { 19 | if(right == null) { 20 | System.out.printf("+++ data = %c is added as a rightChild of %s%n",c,this); 21 | right = new Node(c); 22 | } else { 23 | System.out.printf(" following right child of %s%n",c,this); 24 | right.add(c,sb); 25 | } 26 | } else if(c < this.c) { 27 | if(left == null) { 28 | System.out.printf("+++ data = %c is added as a leftChild of %s%n",c,this); 29 | left = new Node(c); 30 | } else { 31 | System.out.printf(" following left child of %s%n",c,this); 32 | left.add(c,sb); 33 | } 34 | } 35 | } 36 | 37 | public String toString() { 38 | StringBuilder sb = new StringBuilder(); 39 | sb.append('('); 40 | if(left == null) sb.append('-'); 41 | else sb.append(left); 42 | sb.append(' '); 43 | sb.append(c); 44 | sb.append(' '); 45 | if(right == null) sb.append('-'); 46 | else sb.append(right); 47 | sb.append(')'); 48 | return sb.toString(); 49 | } 50 | } 51 | 52 | public class BTree { 53 | Node head; 54 | 55 | public void add(char c) { 56 | System.out.printf("Adding data = %c%n",c); 57 | StringBuilder sb = new StringBuilder(); 58 | if(head == null) { 59 | head = new Node(c); 60 | } else { 61 | head.add(c,sb); 62 | } 63 | System.out.printf("New tree = %s%n%n",head); 64 | } 65 | 66 | public String toString() { 67 | return toString(head); 68 | } 69 | public static String toString(Node node) { 70 | if(node == null) 71 | return "<>"; 72 | return "<"+node+">"; 73 | } 74 | 75 | public static void main(String[] args) { 76 | BTree bt = new BTree(); 77 | for(char c : new char[]{'b','i','g','g','e','r'}) 78 | bt.add(c); 79 | } 80 | } 81 | 82 | -------------------------------------------------------------------------------- /src/basicgraphics/FileUtility.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this license header, choose License Headers in Project Properties. 3 | * To change this template file, choose Tools | Templates 4 | * and open the template in the editor. 5 | */ 6 | package basicgraphics; 7 | 8 | import java.io.File; 9 | import java.net.URI; 10 | import java.net.URL; 11 | 12 | /** 13 | * 14 | * @author sbrandt 15 | */ 16 | public class FileUtility { 17 | 18 | 19 | public static URI findFile(String name) { 20 | int slash = name.replace('\\','/').lastIndexOf('/'); 21 | if(slash > 0) 22 | name = name.substring(slash+1); 23 | File f = findFile(new File("."),name); 24 | if(f == null) 25 | f = findFileI(new File("."),name); 26 | //System.out.println(" --> findFile: name: "+name); 27 | //System.out.println("Search: "+name+" => "+f); 28 | if(f == null) { 29 | return null; 30 | } else { 31 | return f.toURI(); 32 | } 33 | } 34 | 35 | public static File findFile(Class c, String name) { 36 | URL d = c.getResource("."); 37 | return findFile(new File(d.getFile().replace("%20"," ")),name); 38 | } 39 | 40 | static File findFile(File file, String name) { 41 | File[] files = file.listFiles(); 42 | for (File f : files) { 43 | if (f.isDirectory()) { 44 | if(f.getName().startsWith(".")) { 45 | continue; 46 | } else { 47 | File s = findFile(f,name); 48 | if(s != null) 49 | return s; 50 | } 51 | } else if (f.getName().equalsIgnoreCase(name)) { 52 | return f; 53 | } 54 | } 55 | return null; 56 | } 57 | 58 | static File findFileI(File file, String name) { 59 | File[] files = file.listFiles(); 60 | for (File f : files) { 61 | if (f.isDirectory()) { 62 | if(f.getName().startsWith(".")) { 63 | continue; 64 | } else { 65 | File s = findFile(f,name); 66 | if(s != null) 67 | return s; 68 | } 69 | } else if (f.getName().equalsIgnoreCase(name)) { 70 | return f; 71 | } 72 | } 73 | return null; 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /src/basicgraphics/calculator/Auto.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this license header, choose License Headers in Project Properties. 3 | * To change this template file, choose Tools | Templates 4 | * and open the template in the editor. 5 | */ 6 | package basicgraphics.calculator; 7 | 8 | import basicgraphics.BasicFrame; 9 | import java.awt.AWTException; 10 | import java.awt.Component; 11 | import java.awt.Dimension; 12 | import java.awt.Point; 13 | import java.awt.Robot; 14 | import java.awt.event.ActionEvent; 15 | import java.awt.event.ActionListener; 16 | import java.awt.event.InputEvent; 17 | import java.util.logging.Level; 18 | import java.util.logging.Logger; 19 | import javax.swing.JButton; 20 | import javax.swing.JLabel; 21 | import javax.swing.JTextArea; 22 | import javax.swing.text.JTextComponent; 23 | 24 | /** 25 | * 26 | * @author sbrandt 27 | */ 28 | public class Auto { 29 | Robot robot; 30 | public Auto() throws AWTException { 31 | robot = new Robot(); 32 | } 33 | boolean set = false; 34 | ActionListener al = new ActionListener() { 35 | @Override 36 | public void actionPerformed(ActionEvent e) { 37 | set = true; 38 | } 39 | }; 40 | public void press(Component c) { 41 | delay(); 42 | if(c instanceof JButton) { 43 | JButton jb = (JButton)c; 44 | jb.addActionListener(al); 45 | } 46 | set = false; 47 | Point pt = new Point(c.getLocationOnScreen()); 48 | Dimension dim = c.getSize(); 49 | robot.mouseMove(pt.x+dim.width/2, pt.y+dim.height/2); 50 | robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); 51 | robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); 52 | if(c instanceof JButton) { 53 | JButton jb = (JButton)c; 54 | jb.removeActionListener(al); 55 | assert set : "getLocationOnScreen() not working on this computer"; 56 | } 57 | } 58 | 59 | public void press(BasicFrame bf, String b) { 60 | press(bf.getComponent(b)); 61 | } 62 | 63 | private void delay() { 64 | try { 65 | Thread.sleep(100); 66 | } catch (InterruptedException ex) { 67 | } 68 | } 69 | 70 | public String getValue(BasicFrame bf, String txt) { 71 | delay(); 72 | Component c = bf.getComponent(txt); 73 | if(c instanceof JLabel) { 74 | return ((JLabel) c).getText(); 75 | } else if(c instanceof JTextArea) { 76 | return ((JTextArea) c).getText(); 77 | } else if(c instanceof JTextComponent) { 78 | return ((JTextComponent) c).getText(); 79 | } 80 | throw new Error("Not a text component"); 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /src/walkthedog/WalkDog.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this license header, choose License Headers in Project Properties. 3 | * To change this template file, choose Tools | Templates 4 | * and open the template in the editor. 5 | */ 6 | package walkthedog; 7 | 8 | import basicgraphics.BasicFrame; 9 | import basicgraphics.ClockWorker; 10 | import basicgraphics.CollisionEventType; 11 | import basicgraphics.Scene; 12 | import basicgraphics.Sprite; 13 | import basicgraphics.SpriteCollisionEvent; 14 | import basicgraphics.SpriteComponent; 15 | import basicgraphics.Task; 16 | import basicgraphics.images.BackgroundPainter; 17 | import basicgraphics.images.Picture; 18 | import java.awt.Dimension; 19 | 20 | /** 21 | * 22 | * @author sbrandt 23 | */ 24 | class Dog extends Sprite { 25 | public Scene scene2; 26 | Picture basePic; 27 | Dog(Scene sc) { 28 | super(sc); 29 | basePic = new Picture("dog.jpg").transparentBright(0x90).shrinkToMinimum(); 30 | setPicture(basePic); 31 | final double del = .1; 32 | ClockWorker.addTask(new Task() { 33 | @Override 34 | public void run() { 35 | count++; 36 | if (count == 100) { 37 | setHeadingOffset(Math.PI+del); 38 | } else if (count == 200) { 39 | setHeadingOffset(Math.PI-del); 40 | count = 0; 41 | } 42 | } 43 | }); 44 | } 45 | int count = 0; 46 | @Override 47 | public void processEvent(SpriteCollisionEvent ev) { 48 | if(ev.eventType == CollisionEventType.WALL_INVISIBLE) { 49 | if(getVelX() < 0) { 50 | scene2 = migrate(scene2, getX(), getY(), getVelX(), getVelX()); 51 | } 52 | setVel(-getVelX(), 0); 53 | setPicture(getPicture().flipUpDown()); 54 | } 55 | } 56 | } 57 | public class WalkDog { 58 | public static void main(String[] args) { 59 | SpriteComponent sc = new SpriteComponent(); 60 | Scene scene = sc.getScene(); 61 | Scene scene2 = sc.createScene(); 62 | scene.setPainter(new BackgroundPainter(new Picture("park.jpg"))); 63 | scene2.setPainter(new BackgroundPainter(new Picture("park2.jpg"))); 64 | Dog dog = new Dog(sc.getScene()); 65 | dog.scene2 = scene2; 66 | dog.setVel(-1.0, 0); 67 | dog.setY(350); 68 | dog.setX(800); 69 | dog.setHeadingOffset(Math.PI); 70 | 71 | BasicFrame bf = new BasicFrame("Walk the Dog"); 72 | String[][] layout = {{"dog"}}; 73 | bf.setStringLayout(layout); 74 | bf.add("dog",sc); 75 | sc.setPreferredSize(new Dimension(800,400)); 76 | bf.show(); 77 | ClockWorker.addTask(sc.moveSprites()); 78 | ClockWorker.initialize(10); 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /src/basicgraphics/TaskRunner.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this license header, choose License Headers in Project Properties. 3 | * To change this template file, choose Tools | Templates 4 | * and open the template in the editor. 5 | */ 6 | package basicgraphics; 7 | 8 | import java.awt.Component; 9 | import java.io.PrintWriter; 10 | import java.io.StringWriter; 11 | import java.util.LinkedList; 12 | import javax.swing.JOptionPane; 13 | import javax.swing.SwingUtilities; 14 | 15 | /** 16 | * The task runner attempts to avoid the complexity of 17 | * writing threaded programs. Putting the task on the 18 | * event dispatch queue is not enough. It is possible 19 | * for tasks to run simultaneously, even within that 20 | * one thread, because any call to a graphics function 21 | * may pull another task of the event queue and run it. 22 | * Thus we introduce the busy flag and a linked list of 23 | * tasks to ensure that doesn't happen. 24 | * @author sbrandt 25 | */ 26 | public class TaskRunner { 27 | static LinkedList tasks = new LinkedList<>(); 28 | static boolean busy = false; 29 | /** 30 | * Run a task at a later time on the event dispatch thread. 31 | * @param c used to report exceptions 32 | * @param r the task to run 33 | */ 34 | static void runLater(final Component c,final Runnable r) { 35 | Runnable re = new Runnable() { 36 | @Override 37 | public void run() { 38 | tasks.addLast(r); 39 | if(busy) 40 | return; 41 | try { 42 | busy = true; 43 | // Catch up if there's a backlog 44 | for (int i = 0; i < 3; i++) { 45 | if(tasks.isEmpty()) 46 | break; 47 | Runnable next = tasks.removeFirst(); 48 | try { 49 | next.run(); 50 | } catch (Exception e) { 51 | report(e,c); 52 | } 53 | } 54 | } finally { 55 | busy = false; 56 | } 57 | } 58 | }; 59 | SwingUtilities.invokeLater(re); 60 | } 61 | public static void report(Throwable e,Component c) { 62 | if(c == null) 63 | c = BasicFrame.getFrame().getContentPane(); 64 | // We don't want to lose information 65 | // about exceptions! 66 | // First provide to the console. 67 | // Next provide output to the GUI, 68 | // because the console may not be 69 | // visible. 70 | StringWriter sw = new StringWriter(); 71 | PrintWriter pw = new PrintWriter(sw); 72 | e.printStackTrace(pw); 73 | pw.close(); 74 | JOptionPane.showMessageDialog(c, sw.toString()); 75 | System.out.print(sw.toString()); 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /src/prog/game/Dice.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this license header, choose License Headers in Project Properties. 3 | * To change this template file, choose Tools | Templates 4 | * and open the template in the editor. 5 | */ 6 | package prog.game; 7 | 8 | import java.awt.Color; 9 | import java.awt.Dimension; 10 | import java.awt.Graphics; 11 | import java.util.Random; 12 | import javax.swing.JComponent; 13 | 14 | /** 15 | * 16 | * @author sbrandt 17 | */ 18 | public class Dice extends JComponent { 19 | private int spots = -1; 20 | public static final Random RAND = new Random(); 21 | 22 | public Dice() { 23 | // roll(); 24 | } 25 | 26 | public void roll() { 27 | setSpots(1+RAND.nextInt(6)); 28 | } 29 | public void setSpots(int n) { 30 | spots = n; 31 | repaint(); 32 | } 33 | public int getSpots() { 34 | return spots; 35 | } 36 | @Override 37 | public void paint(Graphics g) { 38 | Dimension d = getSize(); 39 | g.setColor(Color.white); 40 | g.fillRect(0, 0, d.width, d.height); 41 | int SS = d.width / 10; 42 | g.setColor(Color.black); 43 | g.drawRect(0, 0, d.width-1, d.height-1); 44 | switch(spots) { 45 | case 1: 46 | g.fillOval(d.width/2-SS, d.height/2-SS, 2*SS, 2*SS); 47 | break; 48 | case 2: 49 | g.fillOval(d.width/4-SS, d.height/4-SS, 2*SS, 2*SS); 50 | g.fillOval(3*d.width/4-SS, 3*d.height/4-SS, 2*SS, 2*SS); 51 | break; 52 | case 3: 53 | g.fillOval(d.width/2-SS, d.height/2-SS, 2*SS, 2*SS); 54 | g.fillOval(d.width/4-SS, d.height/4-SS, 2*SS, 2*SS); 55 | g.fillOval(3*d.width/4-SS, 3*d.height/4-SS, 2*SS, 2*SS); 56 | break; 57 | case 4: 58 | g.fillOval(d.width/4-SS, d.height/4-SS, 2*SS, 2*SS); 59 | g.fillOval(3*d.width/4-SS, 3*d.height/4-SS, 2*SS, 2*SS); 60 | g.fillOval(3*d.width/4-SS, d.height/4-SS, 2*SS, 2*SS); 61 | g.fillOval(d.width/4-SS, 3*d.height/4-SS, 2*SS, 2*SS); 62 | break; 63 | case 5: 64 | g.fillOval(d.width/4-SS, d.height/4-SS, 2*SS, 2*SS); 65 | g.fillOval(3*d.width/4-SS, 3*d.height/4-SS, 2*SS, 2*SS); 66 | g.fillOval(3*d.width/4-SS, d.height/4-SS, 2*SS, 2*SS); 67 | g.fillOval(d.width/4-SS, 3*d.height/4-SS, 2*SS, 2*SS); 68 | g.fillOval(d.width/2-SS, d.height/2-SS, 2*SS, 2*SS); 69 | break; 70 | case 6: 71 | g.fillOval(d.width/4-SS, d.height/4-SS, 2*SS, 2*SS); 72 | g.fillOval(3*d.width/4-SS, 3*d.height/4-SS, 2*SS, 2*SS); 73 | g.fillOval(3*d.width/4-SS, d.height/4-SS, 2*SS, 2*SS); 74 | g.fillOval(d.width/4-SS, 3*d.height/4-SS, 2*SS, 2*SS); 75 | g.fillOval(3*d.width/4-SS, d.height/2-SS, 2*SS, 2*SS); 76 | g.fillOval(d.width/4-SS, d.height/2-SS, 2*SS, 2*SS); 77 | break; 78 | } 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /src/maze/PathFinder.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this license header, choose License Headers in Project Properties. 3 | * To change this template file, choose Tools | Templates 4 | * and open the template in the editor. 5 | */ 6 | package maze; 7 | 8 | import java.util.Queue; 9 | import java.util.Stack; 10 | 11 | /** 12 | * 13 | * @author sbrandt 14 | */ 15 | interface PathFinder { 16 | /** 17 | * Starting from position 'p', examine 18 | * the adjacent cells to 'p' found by 19 | * looking to the north, east, south 20 | * and west. 21 | * 22 | * You can obtain the cell at position 23 | * x and y in the board by using the 24 | * following construct: 25 | * 26 | * Cell c = board[x][y]; 27 | * 28 | * Likewise, you can find the cell to 29 | * the east of x,y by using the code: 30 | * 31 | * Cell c = board[x+1][y]; 32 | * 33 | * Or north of the cell at x,y by using 34 | * this code: 35 | * 36 | * Cell c = board[x][y-1]; 37 | * 38 | * All four adjacent cells on the board 39 | * from x,y can be visualized like this: 40 | * [ ][x ,y-1][ ] 41 | * [x-1,y+0][x ,y ][x+1,y ] 42 | * [ ][x ,y+1][ ] 43 | * 44 | * For each of these four cells: 45 | * 1) if the cell is a wall (has field isWall == true), 46 | * do nothing. 47 | * 2) if the cell is the goal (has field isGoal == true), 48 | * do nothing except updating the sequence (see #4 below). 49 | * 3) if the cell's field named 'sequence' has a value 50 | * greater than zero, do nothing. If the value of 51 | * sequence is nonzero, it means you have previously 52 | * visited this cell. 53 | * 4) Otherwise, add the cell's position to the queue. 54 | * In addition, set the value of 'sequence' on any 55 | * newly added cell to one plus the value 'sequence' of 56 | * the cell at p 57 | * (i.e. 1 + board[p.x][p.y].sequence). 58 | * 59 | * If any positions were added to the queue, 60 | * return true, otherwise return false. 61 | */ 62 | boolean addPathElement(Pos p,Cell[][] m,Queue q); 63 | 64 | /** 65 | * If the queue is empty return false; 66 | * otherwise remove the first Pos from 67 | * the queue and use it to call addPathElement 68 | * then return true. 69 | * 70 | * This method will fill in the entier maze 71 | * with sequence values, each of which will 72 | * be the smallest number of moves needed to 73 | * arrive at that square. 74 | */ 75 | boolean tracePath(Cell[][] m,Queue q); 76 | 77 | /** 78 | * We find the path by starting at the goal and 79 | * looking for adjacent squares with decreasing 80 | * sequence number. 81 | * 82 | * Consider the sequence number 'n' for position 83 | * p (i.e. int n = board[p.x][p.y].sequence). 84 | * 85 | * If n is one, return. 86 | * 87 | * If n is more than one, 88 | * 1) look for a neighboring square with a sequence 89 | * equal to n-1 90 | * 2) when you find one, add its position to the stack, 91 | * and stop looking for others. 92 | * 3) call retracePath on the position you just found. 93 | */ 94 | void retracePath(Pos p,Cell[][] m,Stack s); 95 | } 96 | 97 | -------------------------------------------------------------------------------- /src/maze/MazeViz.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this license header, choose License Headers in Project Properties. 3 | * To change this template file, choose Tools | Templates 4 | * and open the template in the editor. 5 | */ 6 | package maze; 7 | 8 | import basicgraphics.BasicFrame; 9 | import basicgraphics.ClockWorker; 10 | import basicgraphics.SpriteComponent; 11 | import java.awt.Color; 12 | import java.awt.Dimension; 13 | import java.awt.Font; 14 | import java.awt.Graphics; 15 | import java.awt.event.WindowAdapter; 16 | import java.awt.event.WindowEvent; 17 | import java.awt.event.WindowListener; 18 | import javax.swing.JFrame; 19 | import javax.swing.JPanel; 20 | import javax.swing.WindowConstants; 21 | 22 | /** 23 | * 24 | * @author sbrandt 25 | */ 26 | public class MazeViz { 27 | 28 | BasicFrame bf; 29 | Maze maze; 30 | 31 | MazeViz() { 32 | bf = BasicFrame.getFrame(); 33 | if(bf != null) 34 | bf.disposeFrame(); 35 | bf = new BasicFrame("Maze Runner"); 36 | bf.setStringLayout(layout); 37 | bf.add( "C", jp); 38 | } 39 | final static String[][] layout = new String[][]{new String[]{"C"}}; 40 | SpriteComponent jp = new SpriteComponent() { 41 | @Override 42 | public void paintBackground(Graphics g) { 43 | g.setFont(getFont()); 44 | Dimension d = getSize(); 45 | g.setColor(Color.WHITE); 46 | g.fillRect(0, 0, d.width, d.height); 47 | g.setColor(Color.BLACK); 48 | int delx = d.width / maze.sizex; 49 | int dely = d.height / maze.sizey; 50 | for (int i = 0; i < maze.sizex; i++) { 51 | g.drawRect(i * delx, 0, delx, d.height); 52 | } 53 | for (int j = 0; j < maze.sizey; j++) { 54 | g.drawRect(0, j * dely, d.width, dely); 55 | } 56 | for (int i = 0; i < maze.sizex; i++) { 57 | for (int j = 0; j < maze.sizey; j++) { 58 | Cell c = maze.board[i][j]; 59 | if (c.isWall) { 60 | g.setColor(Color.BLACK); 61 | g.fillRect(i * delx, j * dely, delx, dely); 62 | } else if (c.isStart || c.isGoal) { 63 | g.setColor(Color.GREEN); 64 | g.fillRect(i * delx, j * dely, delx, dely); 65 | } 66 | if (c.sequence > 0) { 67 | final int fac = 6; 68 | g.setColor(Color.BLUE); 69 | g.drawString("" + c.sequence, i * delx + delx / fac, (j + 1) * dely - dely / fac); 70 | } 71 | } 72 | } 73 | } 74 | }; 75 | 76 | public Runnable after = new Runnable() { 77 | public void run() {} 78 | }; 79 | public void initMaze(Maze m) { 80 | this.maze = m; 81 | jp.setPreferredSize(new Dimension((int)(500 / 15. * m.sizex), (int)(500 / 15. * m.sizey))); 82 | Font f = new Font("Courier", Font.BOLD, 20); 83 | bf.setAllFonts(f); 84 | bf.jf.addWindowListener(new WindowAdapter() { 85 | @Override 86 | public void windowClosing(WindowEvent we) { 87 | if(after != null) 88 | after.run(); 89 | } 90 | }); 91 | bf.jf.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); 92 | ClockWorker.initialize(10); 93 | ClockWorker.addTask(jp.moveSprites()); 94 | bf.show(); 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /src/basicgraphics/sounds/SoundPlayer.java: -------------------------------------------------------------------------------- 1 | import basicgraphics.FileUtility; 2 | import basicgraphics.images.RuntimeIOException; 3 | import javax.sound.sampled.*; 4 | 5 | import java.net.MalformedURLException; 6 | import java.net.URL; 7 | import java.util.HashMap; 8 | 9 | /** 10 | * 11 | * @author - Jacob Nguyen @jacoobes 12 | * 13 | */ 14 | public class SoundPlayer { 15 | /** 16 | * All clips are stored here. Make sure they are loaded before game starts! 17 | */ 18 | private HashMap mySounds = new HashMap<>(); 19 | 20 | /** 21 | * 22 | * @param name the name of your sound 23 | * @param filename the file location of your .wav file 24 | * @throws Exception 25 | */ 26 | public void newSound(String name, String filename) throws Exception { 27 | URL src = null; 28 | try { 29 | src = new URL(filename); 30 | } catch(MalformedURLException me) { 31 | } 32 | if(src == null) 33 | src = getClass().getResource(filename); 34 | if(src == null) { 35 | src = FileUtility.findFile(filename).toURL(); 36 | if(src == null) { 37 | new RuntimeIOException("Could not load: "+filename).printStackTrace(); 38 | } 39 | } 40 | if(src == null) throw new Exception("Cannot find file"); 41 | Clip c = AudioSystem.getClip(); 42 | AudioInputStream ais = AudioSystem.getAudioInputStream(src); 43 | c.open(ais); 44 | mySounds.put(name, c); 45 | } 46 | 47 | /** 48 | * 49 | * @param name the name of the clip you want to loop 50 | * @param n how many times to loop. Use -1 if you want to loop infinitely 51 | * @throws Exception 52 | */ 53 | public void loop (String name, int n) throws Exception { 54 | mySounds.get(name).loop(n); 55 | } 56 | 57 | /** 58 | * 59 | * @param name stop the given loop 60 | */ 61 | public void stop(String name) { 62 | mySounds.get(name).stop(); 63 | } 64 | /** 65 | * Stops all clips in map 66 | */ 67 | public void stopAll() { 68 | for ( Clip c : mySounds.values() ) 69 | { 70 | c.stop(); 71 | } 72 | } 73 | /** 74 | * Loops all clips in map by n 75 | * @param n how many times to loop 76 | */ 77 | public void loopAll (int n) { 78 | for ( Clip c : mySounds.values() ) 79 | { 80 | c.loop(n); 81 | } 82 | } 83 | 84 | /** 85 | * 86 | * @param name name of clip 87 | * @return the volume of a clip 88 | */ 89 | public float getVolume(String name) { 90 | FloatControl gainControl = (FloatControl) mySounds.get(name).getControl(FloatControl.Type.MASTER_GAIN); 91 | return (float) Math.pow(10f, gainControl.getValue() / 20f); 92 | } 93 | 94 | /** 95 | * 96 | * @param name name of clip 97 | * @param volume how much more volume u want. Range is 0f .. 1f 98 | */ 99 | public void setVolume(String name, float volume) { 100 | if (volume < 0f || volume > 1f) 101 | throw new IllegalArgumentException("Volume not valid: " + volume); 102 | FloatControl gainControl = (FloatControl) mySounds.get(name).getControl(FloatControl.Type.MASTER_GAIN); 103 | gainControl.setValue(20f * (float) Math.log10(volume)); 104 | } 105 | } -------------------------------------------------------------------------------- /src/basicgraphics/calculator/MarsData.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this license header, choose License Headers in Project Properties. 3 | * To change this template file, choose Tools | Templates 4 | * and open the template in the editor. 5 | */ 6 | package basicgraphics.calculator; 7 | 8 | import java.io.File; 9 | import java.io.FileWriter; 10 | import java.io.IOException; 11 | import java.io.PrintWriter; 12 | import java.net.URL; 13 | import java.util.Scanner; 14 | import java.util.regex.MatchResult; 15 | import java.util.regex.Pattern; 16 | 17 | /** 18 | * This class fetches live data about Mars from the internet. 19 | * 20 | * @author sbrandt 21 | */ 22 | public class MarsData { 23 | 24 | public double rightAscension; 25 | public double declination; 26 | public double sunDistance; 27 | public double earthDistance; 28 | 29 | public String toString() { 30 | StringBuilder sb = new StringBuilder(); 31 | sb.append("MarsData{"); 32 | sb.append(String.format("rightAscension=%.6f,", rightAscension)); 33 | sb.append(String.format("declination=%.6f,", declination)); 34 | sb.append(String.format("sunDistance=%.6f,", sunDistance)); 35 | sb.append(String.format("earthDistance=%.6f", earthDistance)); 36 | sb.append("}"); 37 | return sb.toString(); 38 | } 39 | 40 | public MarsData() { 41 | 42 | try { 43 | Pattern rightAscensionP = Pattern.compile("Right.*Ascension:.*>\\s*([-\\d.]+)\\s*<"); 44 | Pattern declinationP = Pattern.compile("Declination:.*>\\s*([-\\d.]+)\\s*<"); 45 | Pattern sunDistanceP = Pattern.compile("Sun.*Distance:.*>\\s*([-\\d.]+)\\s*<"); 46 | Pattern earthDistanceP = Pattern.compile("Earth.*Distance:.*>\\s*([-\\d.]+)\\s*<"); 47 | Scanner sc = null; 48 | 49 | String info = System.getProperty("user.home", ".") + "/mars_info.txt"; 50 | File finfo = new File(info); 51 | if (finfo.exists() && finfo.lastModified() + 10 * 60 * 1000 > System.currentTimeMillis()) { 52 | sc = new Scanner(finfo); 53 | } else { 54 | URL url = new URL("https://theskylive.com/mars-tracker"); 55 | sc = new Scanner(url.openStream()); 56 | } 57 | while (sc.hasNextLine()) { 58 | if (sc.findInLine(rightAscensionP) != null) { 59 | MatchResult mr = sc.match(); 60 | rightAscension = Double.parseDouble(mr.group(1)); 61 | } 62 | if (sc.findInLine(declinationP) != null) { 63 | MatchResult mr = sc.match(); 64 | declination = Double.parseDouble(mr.group(1)); 65 | } 66 | if (sc.findInLine(sunDistanceP) != null) { 67 | MatchResult mr = sc.match(); 68 | sunDistance = Double.parseDouble(mr.group(1)); 69 | } 70 | if (sc.findInLine(earthDistanceP) != null) { 71 | MatchResult mr = sc.match(); 72 | earthDistance = Double.parseDouble(mr.group(1)); 73 | } 74 | sc.nextLine(); 75 | } 76 | PrintWriter pw = new PrintWriter(finfo); 77 | pw.printf("Right Ascension: >%f<%n",rightAscension); 78 | pw.printf("Declination: >%f<%n",declination); 79 | pw.printf("Earth Distance: >%f<%n",earthDistance); 80 | pw.printf("Sun Distance: >%f<%n",sunDistance); 81 | pw.close(); 82 | } catch (IOException ioe) { 83 | } 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /src/basicgraphics/BasicDialog.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Click nbfs://nbhost/SystemFileSystem/Templates/Licenses/license-default.txt to change this license 3 | * Click nbfs://nbhost/SystemFileSystem/Templates/Classes/Class.java to edit this template 4 | */ 5 | package basicgraphics; 6 | 7 | import basicgraphics.images.Picture; 8 | import java.awt.Component; 9 | import java.awt.Container; 10 | import java.awt.Graphics; 11 | import javax.swing.Icon; 12 | import javax.swing.JLabel; 13 | import javax.swing.JOptionPane; 14 | 15 | /** 16 | * A slightly simplified interface to JOptionPane. 17 | * 18 | * @author steve 19 | */ 20 | public class BasicDialog { 21 | 22 | public final static Icon EMPTY_ICON = new Icon() { 23 | @Override 24 | public void paintIcon(Component c, Graphics g, int x, int y) { 25 | } 26 | 27 | @Override 28 | public int getIconWidth() { 29 | return 1; 30 | } 31 | 32 | @Override 33 | public int getIconHeight() { 34 | return 1; 35 | } 36 | }; 37 | 38 | public static final String YES = "YES", NO = "NO", CANCEL = "CANCEL"; 39 | 40 | public static void getOK(String message) { 41 | Container c = BasicFrame.getFrame().getContentPane(); 42 | JOptionPane.showMessageDialog(c, message); 43 | } 44 | 45 | public static String getYesNoCancel(String message) { 46 | Container c = BasicFrame.getFrame().getContentPane(); 47 | int rc = JOptionPane.showConfirmDialog(c, message, "Yes/No/Cancel", JOptionPane.YES_NO_CANCEL_OPTION); 48 | if (rc == JOptionPane.YES_OPTION) { 49 | return YES; 50 | } 51 | if (rc == JOptionPane.NO_OPTION) { 52 | return NO; 53 | } 54 | assert rc == JOptionPane.CANCEL_OPTION; 55 | return CANCEL; 56 | } 57 | 58 | public static String getYesNo(String message) { 59 | Container c = BasicFrame.getFrame().getContentPane(); 60 | int rc = JOptionPane.showConfirmDialog(c, message, "Yes/No", JOptionPane.YES_NO_OPTION); 61 | if (rc == JOptionPane.YES_OPTION) { 62 | return YES; 63 | } 64 | assert rc == JOptionPane.NO_OPTION; 65 | return NO; 66 | } 67 | 68 | public static String getOption(String message, String title, String[] optionStrs, String initialStr) { 69 | return getOption(message, title, EMPTY_ICON, optionStrs, initialStr); 70 | } 71 | public static String getOption(String message, String title, Icon icon, String[] optionStrs, String initialStr) { 72 | Component c = BasicFrame.getFrame().getContentPane(); 73 | Object[] options = new Object[optionStrs.length]; 74 | assert initialStr != null; 75 | Object initial = initialStr; 76 | boolean found = false; 77 | for (int i = 0; i < optionStrs.length; i++) { 78 | String s = optionStrs[i]; 79 | assert s != null; 80 | if (s.equals(initial)) { 81 | found = true; 82 | } 83 | options[i] = s; 84 | } 85 | assert found : "Initial string not in options"; 86 | 87 | Object rc = JOptionPane.showInputDialog( 88 | c, message, title, JOptionPane.PLAIN_MESSAGE, icon, options, initial); 89 | return (String) rc; 90 | } 91 | 92 | public static void main(String[] args) { 93 | // Create a basic application 94 | BasicFrame bf = new BasicFrame("opt"); 95 | final Icon sarah = new Picture("Sarah.png").getIcon(); 96 | bf.createSingletonLayout(new JLabel(sarah)); 97 | bf.show(); 98 | 99 | // Prompt using an icon 100 | String option = getOption("Which fruit?", "Fruit Selection", sarah, new String[]{"Apple", "Pear", "Orange", "Banana"}, "Apple"); 101 | System.out.println("option: " + option); 102 | } 103 | } 104 | -------------------------------------------------------------------------------- /nbproject/private/private.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | file:/C:/Users/steve/repos/BasicGraphics/src/marslander/Rocket.java 7 | file:/C:/Users/steve/repos/BasicGraphics/src/basicgraphics/BasicFrame.java 8 | file:/C:/Users/steve/repos/BasicGraphics/src/basicflyer/Falcon.java 9 | file:/C:/Users/steve/repos/BasicGraphics/src/basicgraphics/sounds/SoundPlayer.java 10 | file:/C:/Users/steve/repos/BasicGraphics/src/basicgraphics/images/Picture.java 11 | file:/C:/Users/steve/repos/BasicGraphics/src/langtonsant/AntSprite.java 12 | file:/C:/Users/steve/repos/BasicGraphics/src/beowulf/dragons/Main.java 13 | file:/C:/Users/steve/repos/BasicGraphics/src/langtonsant/Ant.java 14 | file:/C:/Users/steve/repos/BasicGraphics/src/lightsout/Tile.java 15 | file:/C:/Users/steve/repos/BasicGraphics/src/basicgraphics/examples/BasicGraphics.java 16 | file:/C:/Users/steve/repos/BasicGraphics/src/basicflyer/Plasma.java 17 | file:/C:/Users/steve/repos/BasicGraphics/src/walkthedog/WalkDog.java 18 | file:/C:/Users/steve/repos/BasicGraphics/src/marslander/LandingPad.java 19 | file:/C:/Users/steve/repos/BasicGraphics/src/boardgame/Player.java 20 | file:/C:/Users/steve/repos/BasicGraphics/src/robosorter/Mover.java 21 | file:/C:/Users/steve/repos/BasicGraphics/src/basicshooter/Bullet.java 22 | file:/C:/Users/steve/repos/BasicGraphics/src/boardgame/Board.java 23 | file:/C:/Users/steve/repos/BasicGraphics/src/basicgraphics/examples/Bat.java 24 | file:/C:/Users/steve/repos/BasicGraphics/src/lightsout/LightsOutGame.java 25 | file:/C:/Users/steve/repos/BasicGraphics/src/basicflyer/Flyer.java 26 | file:/C:/Users/steve/repos/BasicGraphics/src/basicgraphics/examples/BasicGraphics2.java 27 | file:/C:/Users/steve/repos/BasicGraphics/src/basicshooter/Enemy.java 28 | file:/C:/Users/steve/repos/BasicGraphics/src/basicgraphics/examples/Foo.java 29 | file:/C:/Users/steve/repos/BasicGraphics/src/maze/Maze.java 30 | file:/C:/Users/steve/repos/BasicGraphics/src/boardgame/Game.java 31 | file:/C:/Users/steve/repos/BasicGraphics/src/basicgraphics/FileUtility.java 32 | file:/C:/Users/steve/repos/BasicGraphics/src/prog/game/Game2.java 33 | file:/C:/Users/steve/repos/BasicGraphics/src/basicgraphics/Util.java 34 | file:/C:/Users/steve/repos/BasicGraphics/src/basicgraphics/ClockWorker.java 35 | file:/C:/Users/steve/repos/BasicGraphics/src/prog/game/ProgSpriteComponent.java 36 | file:/C:/Users/steve/repos/BasicGraphics/src/prog/game/Dice.java 37 | file:/C:/Users/steve/repos/BasicGraphics/src/robosorter/MartianEgg.java 38 | file:/C:/Users/steve/repos/BasicGraphics/src/robosorter/Robo.java 39 | file:/C:/Users/steve/repos/BasicGraphics/src/marslander/MarsLander.java 40 | file:/C:/Users/steve/repos/BasicGraphics/src/basicgraphics/SpriteCollisionEvent.java 41 | file:/C:/Users/steve/repos/BasicGraphics/src/basicshooter/Game.java 42 | file:/C:/Users/steve/repos/BasicGraphics/src/basicshooter/Shooter.java 43 | file:/C:/Users/steve/repos/BasicGraphics/src/basicgraphics/Scene.java 44 | file:/C:/Users/steve/repos/BasicGraphics/src/basicgraphics/SpriteComponent.java 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /src/robosorter/Board.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this license header, choose License Headers in Project Properties. 3 | * To change this template file, choose Tools | Templates 4 | * and open the template in the editor. 5 | */ 6 | package robosorter; 7 | 8 | import basicgraphics.Sprite; 9 | 10 | /** 11 | * 12 | * @author sbrandt 13 | */ 14 | public class Board { 15 | 16 | MartianEgg[][] cells = new MartianEgg[Robo.NX][]; 17 | 18 | public Board() { 19 | for (int i = 0; i < cells.length; i++) { 20 | cells[i] = new MartianEgg[Robo.NY]; 21 | } 22 | } 23 | 24 | public void set(MartianEgg me, int x, int y) { 25 | if (me == null) { 26 | return; 27 | } 28 | assert x >= 0 && x < Robo.NX; 29 | assert y >= 0 && y < Robo.NY; 30 | cells[x][y] = me; 31 | me.setX(Robo.PADDING + Robo.BLOCK_SIZE * x); 32 | me.setY(Robo.PADDING + Robo.BLOCK_SIZE * y); 33 | } 34 | 35 | Mover m; 36 | 37 | public void move(final int x2, final int y2) { 38 | System.out.printf("move(%d,%d)%n",x2,y2); 39 | move(x2, y2, false); 40 | } 41 | 42 | public void carry(final int x2, final int y2) { 43 | System.out.printf("carry(%d,%d)%n",x2,y2); 44 | move(x2, y2, true); 45 | } 46 | 47 | public void move(final Mover sp, final MartianEgg carry,final int delx, final int dely) { 48 | // System.out.printf("move(%d,%d)%n",delx,dely); 49 | m.actions.add(new Runnable() { 50 | public void run() { 51 | m.count = Math.max(Math.abs(delx),Math.abs(dely))*Robo.BLOCK_SIZE / Robo.SPEED; 52 | // System.out.printf("count=%d%n", m.count); 53 | if (delx < 0) { 54 | sp.setVel(-Robo.SPEED, sp.getVelY()); 55 | if(carry != null) 56 | carry.setVel(-Robo.SPEED, sp.getVelY()); 57 | } else if (delx > 0) { 58 | sp.setVel(Robo.SPEED, sp.getVelY()); 59 | if(carry != null) 60 | carry.setVel(Robo.SPEED, carry.getVelY()); 61 | } else if (dely < 0) { 62 | sp.setVelY(-Robo.SPEED); 63 | if(carry != null) 64 | carry.setVelY(-Robo.SPEED); 65 | } else if (dely > 0) { 66 | // System.out.printf("setVelY(%d)%n", Robo.SPEED); 67 | sp.setVelY(Robo.SPEED); 68 | if(carry != null) 69 | carry.setVelY(Robo.SPEED); 70 | } 71 | } 72 | }); 73 | m.actions.add(new Runnable() { 74 | public void run() { 75 | sp.setVel(0,0); 76 | if(carry != null) { 77 | carry.setVel(0,0); 78 | } 79 | } 80 | }); 81 | } 82 | 83 | public void move(final int x2, final int y2, final boolean carry) { 84 | assert x2 >= 0 && x2 < cells.length : "x2="+x2; 85 | assert y2 >= 0 && y2 < cells[0].length : "y2="+y2; 86 | final MartianEgg[] oa = new MartianEgg[2]; 87 | for (int j = 0; j < cells[0].length; j++) { 88 | for (int i = 0; i < cells.length; i++) { 89 | if(i == x2 && j == y2) { 90 | // System.out.print(">"); 91 | } else { 92 | // System.out.print(" "); 93 | } 94 | if (cells[i][j] != null) { 95 | // System.out.print("X"); 96 | } else { 97 | // System.out.print("-"); 98 | } 99 | } 100 | // System.out.println(); 101 | } 102 | oa[0] = cells[m.x][m.y]; 103 | oa[1] = cells[x2][y2]; 104 | if (carry) { 105 | assert oa[0] != null : "m.x="+m.x+",m.y="+m.y; 106 | assert oa[1] == null; 107 | m.carrying = oa[0]; 108 | cells[m.x][m.y] = null; 109 | 110 | } 111 | if(m.y < y2) { 112 | move(m,m.carrying,0,1); 113 | m.y++; 114 | } else if(m.y > y2) { 115 | m.y--; 116 | move(m,m.carrying,0,-1); 117 | } 118 | move(m,m.carrying,x2 - m.x,0); 119 | if(m.y < y2) { 120 | move(m,m.carrying,0,1); 121 | } else if(m.y > y2) { 122 | move(m,m.carrying,0,-1); 123 | } 124 | if(carry) 125 | cells[x2][y2] = oa[0]; 126 | // System.out.printf("obs=%s,%s,%s%n",oa[0],oa[1],m.carrying); 127 | m.carrying = null; 128 | m.x = x2; m.y = y2; 129 | } 130 | } 131 | -------------------------------------------------------------------------------- /src/basicgraphics/ByNameLayout.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this license header, choose License Headers in Project Properties. 3 | * To change this template file, choose Tools | Templates 4 | * and open the template in the editor. 5 | */ 6 | package basicgraphics; 7 | 8 | import java.awt.Component; 9 | import java.awt.Container; 10 | import java.awt.Font; 11 | import java.awt.GridBagConstraints; 12 | import java.awt.GridBagLayout; 13 | import java.util.ArrayList; 14 | import java.util.HashMap; 15 | import java.util.Map; 16 | import javax.swing.JFrame; 17 | import javax.swing.JLabel; 18 | 19 | /** 20 | * 21 | * @author sbrandt 22 | */ 23 | public class ByNameLayout { 24 | final private GridBagLayout gbl = new GridBagLayout(); 25 | final private GridBagConstraints gbc = new GridBagConstraints(); 26 | final private String[][] layout; 27 | final private Container container; 28 | final private Map map = new HashMap<>(); 29 | final static private Component BAD = new BadComponent(); 30 | public ByNameLayout(String[][] layoutNames,Container c) { 31 | this.container = c; 32 | c.setLayout(gbl); 33 | gbc.weightx = 1.0; 34 | gbc.weighty = 1.0; 35 | gbc.fill = GridBagConstraints.BOTH; 36 | String[][] s = new String[layoutNames.length][]; 37 | for(int i=0;i maxI) maxI = i; 65 | if(j < minJ) minJ = j; 66 | if(j > maxJ) maxJ = j; 67 | found = true; 68 | } 69 | } 70 | } 71 | if(!found) throw new BasicLayoutException("No location '"+loc+"' in layout"); 72 | for(int i=minI;i <= maxI;i++) { 73 | for(int j=minJ;j <= maxJ;j++) { 74 | if(!loc.equals(layout[i][j])) 75 | throw new BasicLayoutException("Bad value at i="+i+" j="+j+" should be '"+loc+"'"); 76 | } 77 | } 78 | int height = maxI-minI+1; 79 | int width = maxJ-minJ+1; 80 | gbc.gridx = minJ; 81 | gbc.gridy = minI; 82 | gbc.gridwidth = width; 83 | gbc.gridheight = height; 84 | // gbc.weightx = height; 85 | // gbc.weighty = width; 86 | 87 | System.out.println("Add component i="+gbc.gridx+", j="+gbc.gridy+ 88 | ", w="+gbc.gridwidth+", h="+gbc.gridheight); 89 | container.add(component, gbc); 90 | } 91 | 92 | public static void main(String[] args) { 93 | JFrame jf = new JFrame("By Name"); 94 | Font f = new Font("Courier", Font.BOLD, 50); 95 | Container pane = jf.getContentPane(); 96 | String[][] s = { 97 | {"a","b","c"}, 98 | {"d","d","d"} 99 | }; 100 | ByNameLayout bnl = new ByNameLayout(s, pane); 101 | bnl.add("a",new JLabel("Ape")); 102 | bnl.add("b",new JLabel("Bear")); 103 | bnl.add("c",new JLabel("Cat")); 104 | bnl.add("d",new JLabel("Dungeon",JLabel.CENTER)); 105 | bnl.setFont(f); 106 | System.out.println("Ready"); 107 | jf.pack(); 108 | jf.show(true); 109 | } 110 | 111 | public ArrayList all() { 112 | return new ArrayList<>(map.values()); 113 | } 114 | 115 | public void setFont(Font f) { 116 | for(Component v : map.values()) { 117 | v.setFont(f); 118 | } 119 | } 120 | } 121 | -------------------------------------------------------------------------------- /src/robosorter/EggSorter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this license header, choose License Headers in Project Properties. 3 | * To change this template file, choose Tools | Templates 4 | * and open the template in the editor. 5 | */ 6 | package robosorter; 7 | 8 | import java.util.Random; 9 | import java.util.logging.Level; 10 | import java.util.logging.Logger; 11 | 12 | /** 13 | * 14 | * @author sbrandt 15 | */ 16 | public class EggSorter { 17 | public final Random RAND = new Random(); 18 | public void sort_(Mover m,Board board) { 19 | board.move(0,2); 20 | board.carry(0,0); 21 | board.carry(0,1); 22 | board.carry(3,1); 23 | board.carry(2,1); 24 | } 25 | // Bubble sorter 26 | public void bsort(Mover mv,Board board) { 27 | boolean done = false; 28 | while (!done) { 29 | done = true; 30 | for (int i = 1; i < board.cells.length; i++) { 31 | MartianEgg m1 = board.cells[i - 1][2]; 32 | MartianEgg m2 = board.cells[i][2]; 33 | if (m1.num > m2.num) { 34 | board.move(i - 1, 2); 35 | board.carry(i - 1, 0); 36 | board.move(i, 2); 37 | board.carry(i - 1, 2); 38 | board.move(i - 1, 0); 39 | board.carry(i, 2); 40 | done = false; 41 | } 42 | } 43 | } 44 | } 45 | public void msort(Mover mv,Board board) { 46 | msort(mv,board,0,board.cells.length); 47 | } 48 | void msort(Mover mv,Board board,int start,int end) { 49 | if(end - start < 2) 50 | return; 51 | int mid = (start+end)/2; 52 | msort(mv,board,start,mid); 53 | msort(mv,board,mid,end); 54 | int upper=0, lower=0; 55 | for(int i=start;i upper) { 62 | from = 2; 63 | to = 0; 64 | } 65 | 66 | for (int i = start; i < end; i++) { 67 | if (board.cells[i][to] != null) { 68 | assert board.cells[i][from] == null; 69 | board.move(i, to); 70 | board.carry(i, from); 71 | } 72 | } 73 | int i1 = start, i2 = mid, i0 = start; 74 | while(i1 < mid && i2 < end) { 75 | if(board.cells[i1][from].num < board.cells[i2][from].num) { 76 | board.move(i1++,from); 77 | board.carry(i0++,to); 78 | } else { 79 | board.move(i2++,from); 80 | board.carry(i0++,to); 81 | } 82 | } 83 | while(i1 < mid) { 84 | board.move(i1++,from); 85 | board.carry(i0++, to); 86 | } 87 | while(i2 < end) { 88 | board.move(i2++,from); 89 | board.carry(i0++,to); 90 | } 91 | assert i1==mid; 92 | assert i2==end; 93 | assert i0==end; 94 | for(int i=start;i me.num) { 127 | board.move(i,2-row); 128 | board.carry(--i2,row); 129 | } 130 | } 131 | int imid = i1; 132 | for(int i=start;i() { 100 | @Override 101 | public void collision(Enemy sp1, Shooter sp2) { 102 | Enemy.clip.play(); 103 | sp1.destroy(); 104 | sp2.destroy(); 105 | JOptionPane.showMessageDialog(sc, "You lose! Game Over!"); 106 | System.exit(0); 107 | } 108 | }); 109 | sc.addSpriteSpriteCollisionListener(Enemy.class, Bullet.class, new SpriteSpriteCollisionListener() { 110 | @Override 111 | public void collision(Enemy sp1, Bullet sp2) { 112 | Enemy.clip.play(); 113 | sp1.destroy(); 114 | sp2.destroy(); 115 | enemyCount--; 116 | if (enemyCount == 0) { 117 | JOptionPane.showMessageDialog(sc, "You win! Game Over!"); 118 | System.exit(0); 119 | } 120 | } 121 | }); 122 | 123 | bf.show(); 124 | ClockWorker.initialize(10); 125 | ClockWorker.addTask(sc.moveSprites()); 126 | } 127 | 128 | public static void main(String[] args) { 129 | Game g = new Game(); 130 | g.run(); 131 | } 132 | } 133 | -------------------------------------------------------------------------------- /src/basicgraphics/calculator/Calculator.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this license header, choose License Headers in Project Properties. 3 | * To change this template file, choose Tools | Templates 4 | * and open the template in the editor. 5 | */ 6 | package basicgraphics.calculator; 7 | 8 | import basicgraphics.BasicFrame; 9 | import java.awt.Font; 10 | import java.awt.event.ActionEvent; 11 | import java.awt.event.ActionListener; 12 | import java.text.DecimalFormat; 13 | import javax.swing.JButton; 14 | import javax.swing.JLabel; 15 | 16 | /** 17 | * 18 | * @author sbrandt 19 | */ 20 | public class Calculator { 21 | public final static String[][] layout = { 22 | {"D","D","D","C"}, 23 | {"1","2","3","+"}, 24 | {"4","5","6","-"}, 25 | {"7","8","9","*"}, 26 | {"0",".","=","/"} 27 | }; 28 | double value_, previousValue, memory; 29 | String operator; 30 | /** 31 | * This value keeps getting multiplied by .1 32 | * after we click the "." key, allowing us to 33 | * update the current value by the right fraction of one. 34 | */ 35 | double decimal=1.0; 36 | /* 37 | * The current sign, +1 or -1. 38 | */ 39 | double sgn=1.0; 40 | JLabel display = new JLabel("0",JLabel.CENTER); 41 | public BasicFrame bf = new BasicFrame("Martian Calculator"); 42 | public double getValue() { 43 | return value_ * sgn; 44 | } 45 | /** 46 | * Set the current value. Note that the calculator GUI 47 | * won't reflect the new value until you call update(). 48 | */ 49 | public void setValue(double v) { 50 | if(v < 0) { 51 | sgn = -1.0; 52 | value_ = -v; 53 | } else { 54 | sgn = 1.0; 55 | value_ = v; 56 | } 57 | } 58 | 59 | public void init() { 60 | bf.setStringLayout(layout); 61 | bf.add("D",display); 62 | 63 | for(int i=0;i<=9;i++) { 64 | final int key = i; 65 | JButton b = new JButton(""+i); 66 | b.addActionListener(new ActionListener() { 67 | @Override 68 | public void actionPerformed(ActionEvent e) { 69 | if(decimal == 1.0) { 70 | value_ = 10*value_+key; 71 | } else { 72 | value_ = value_ + key*decimal; 73 | decimal *= 0.1; 74 | } 75 | update(); 76 | } 77 | }); 78 | bf.add(""+i, b); 79 | } 80 | for(String s : new String[]{"+","-","/","*","="}) { 81 | final String op = s; 82 | JButton b = new JButton(op); 83 | b.addActionListener(new ActionListener() { 84 | @Override 85 | public void actionPerformed(ActionEvent e) { 86 | if("=".equals(op)) { 87 | calc(operator); 88 | setValue(previousValue); 89 | operator = null; 90 | } else { 91 | previousValue = getValue(); 92 | setValue(0.0); 93 | operator = op; 94 | sgn = 1.0; 95 | } 96 | decimal = 1.0; 97 | update(); 98 | } 99 | }); 100 | bf.add(op,b); 101 | } 102 | 103 | // The text on the button is "Clr" 104 | JButton clear = new JButton("Clr"); 105 | clear.addActionListener(new ActionListener() { 106 | @Override 107 | public void actionPerformed(ActionEvent e) { 108 | setValue(0.0); 109 | previousValue = 0; 110 | operator = null; 111 | decimal = 1.0; 112 | update(); 113 | } 114 | }); 115 | // The place of the button in the layout is 116 | // given by "C". 117 | bf.add("C",clear); 118 | 119 | JButton dot = new JButton("."); 120 | dot.addActionListener(new ActionListener() { 121 | @Override 122 | public void actionPerformed(ActionEvent e) { 123 | decimal *= .1; 124 | } 125 | }); 126 | bf.add(".",dot); 127 | 128 | Font f = new Font("Courier",Font.BOLD,30); 129 | bf.setAllFonts(f); 130 | bf.show(); 131 | } 132 | public void calc(String op) { 133 | if ("+".equals(op)) { 134 | previousValue = previousValue + getValue(); 135 | } else if ("-".equals(op)) { 136 | previousValue = previousValue - getValue(); 137 | } else if ("*".equals(op)) { 138 | previousValue = previousValue * getValue(); 139 | } else if ("/".equals(op)) { 140 | previousValue = previousValue / getValue(); 141 | } 142 | } 143 | final static DecimalFormat df = new DecimalFormat("#.######"); 144 | public void update() { 145 | if(operator == null) { 146 | display.setText(df.format(getValue())); 147 | } else { 148 | display.setText(df.format(previousValue)+operator+df.format(getValue())); 149 | } 150 | } 151 | public static void main(String[] args) { 152 | Calculator c = new Calculator(); 153 | c.init(); 154 | } 155 | } 156 | -------------------------------------------------------------------------------- /src/basicgraphics/BasicContainer.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this license header, choose License Headers in Project Properties. 3 | * To change this template file, choose Tools | Templates 4 | * and open the template in the editor. 5 | */ 6 | package basicgraphics; 7 | 8 | import basicgraphics.images.Painter; 9 | import java.awt.Component; 10 | import java.awt.Container; 11 | import java.awt.Graphics; 12 | import java.awt.GridBagConstraints; 13 | import java.awt.GridBagLayout; 14 | import java.awt.LayoutManager; 15 | import java.util.ArrayList; 16 | import java.util.HashMap; 17 | import java.util.List; 18 | import java.util.Map; 19 | import javax.swing.JComponent; 20 | 21 | /** 22 | * This is a container that can be laid out as easily as a BasicFrame. 23 | * @author sbrandt 24 | */ 25 | public class BasicContainer extends Container { 26 | 27 | private final Map components = new HashMap<>(); 28 | 29 | GridBagLayout gbl = new GridBagLayout(); 30 | GridBagConstraints gbc = new GridBagConstraints(); 31 | ArrayList> cells = new ArrayList<>(); 32 | 33 | public BasicContainer() { 34 | setLayout(gbl); 35 | } 36 | 37 | /** 38 | * Sets the layout of this frame to a simple layout with a single centered component. 39 | * @param mainComponent The component. 40 | */ 41 | public void createSingletonLayout(JComponent mainComponent) { 42 | this.setStringLayout(new String[][] {{"center"}}); 43 | this.add("center", mainComponent); 44 | } 45 | 46 | /** 47 | * Enables you to design your screen with a 2D ascii array. The design takes 48 | * the form of a rectangular grid in which logically rectangular regions on 49 | * the screen are mapped to display components. Java determines the size of 50 | * the individual cells in the grid, based on the name. 51 | * 52 | * @param loc - One of the names in the layout. 53 | * @param jc - The component that should be placed at location loc. 54 | */ 55 | public void add(String loc, JComponent jc) { 56 | if(layout == null) { 57 | super.add(loc, jc); 58 | return; 59 | } 60 | int minI = Integer.MAX_VALUE, maxI = Integer.MIN_VALUE; 61 | int minJ = Integer.MAX_VALUE, maxJ = Integer.MIN_VALUE; 62 | boolean found = false; 63 | for (int i = 0; i < layout.length; i++) { 64 | for (int j = 0; j < layout[i].length; j++) { 65 | if (loc.equals(layout[i][j])) { 66 | if (i < minI) { 67 | minI = i; 68 | } 69 | if (i > maxI) { 70 | maxI = i; 71 | } 72 | if (j < minJ) { 73 | minJ = j; 74 | } 75 | if (j > maxJ) { 76 | maxJ = j; 77 | } 78 | found = true; 79 | } 80 | } 81 | } 82 | if (!found) { 83 | throw new BasicLayoutException("No location '" + loc + "' in layout"); 84 | } 85 | for (int i = minI; i <= maxI; i++) { 86 | for (int j = minJ; j <= maxJ; j++) { 87 | if (!loc.equals(layout[i][j])) { 88 | throw new BasicLayoutException("Bad value at i=" + i + " j=" + j + " should be '" + loc + "'"); 89 | } 90 | } 91 | } 92 | int width = maxI - minI + 1; 93 | int height = maxJ - minJ + 1; 94 | System.out.printf("add(%s,%d,%d,%d,%d)%n",loc,minI,minJ,width,height); 95 | add(loc, jc, minJ, minI, height, width); 96 | } 97 | 98 | private void add(String name, Component c, int x, int y, int xw, int yw) { 99 | if (components.containsKey(name)) { 100 | throw new GuiException("Two components with the same name: " + name); 101 | } 102 | 103 | gbc.gridx = x; 104 | gbc.gridy = y; 105 | gbc.gridwidth = xw; 106 | gbc.gridheight = yw; 107 | gbc.weightx = xw; 108 | gbc.weighty = yw; 109 | 110 | // Ensure the number of cells 111 | while (cells.size() < x + xw) { 112 | cells.add(new ArrayList()); 113 | } 114 | for (int i = 0; i < xw; i++) { 115 | for (int j = 0; j < yw; j++) { 116 | int xv = x + i; 117 | int yv = y + j; 118 | ArrayList row = cells.get(xv); 119 | while (row.size() <= yv) { 120 | row.add(null); 121 | } 122 | String owner = row.get(yv); 123 | if (owner != null) { 124 | throw new GuiException("Conflict of ownership at x=" + xv + " y=" + yv + " owner1=" + owner + " owner2=" + name); 125 | } 126 | row.set(yv, name); 127 | } 128 | } 129 | components.put(name, c); 130 | System.out.println("put(" + name + ")"); 131 | add(c, gbc); 132 | } 133 | 134 | String[][] layout; 135 | 136 | public void setStringLayout(String[][] lay2) { 137 | layout = lay2; 138 | } 139 | public void setStringLayout(List> lay2) { 140 | layout = new String[lay2.size()][]; 141 | for(int i=0;i row = lay2.get(i); 143 | String[] row2 = new String[row.size()]; 144 | for(int j=0;j= maxIteration()) { 139 | Color c = Color.white; 140 | if(iteration() + bloom/4 < maxIteration()) 141 | c = Color.yellow; 142 | pl.setPicture( 143 | Plasma.makeBall(c,PLASMA_SIZE + iteration()-steps+bloom)); 144 | } 145 | if(iteration() == maxIteration()) { 146 | pl.destroy(); 147 | boom.playOverlapping(); 148 | } 149 | } 150 | }); 151 | clip.playOverlapping(); 152 | } 153 | } 154 | }); 155 | 156 | ClockWorker.addTask(sc.moveSprites()); 157 | } 158 | } 159 | -------------------------------------------------------------------------------- /src/basicgraphics/sounds/ReusableClip.java: -------------------------------------------------------------------------------- 1 | package basicgraphics.sounds; 2 | 3 | import basicgraphics.BasicFrame; 4 | import basicgraphics.FileUtility; 5 | import basicgraphics.TaskRunner; 6 | import basicgraphics.images.RuntimeIOException; 7 | import java.net.URI; 8 | import java.net.URL; 9 | import java.net.MalformedURLException; 10 | import java.net.URISyntaxException; 11 | import java.util.LinkedList; 12 | import java.util.concurrent.ExecutorService; 13 | import java.util.concurrent.Executors; 14 | import javax.sound.sampled.AudioInputStream; 15 | import javax.sound.sampled.AudioSystem; 16 | 17 | import javax.sound.sampled.AudioFormat; 18 | import javax.sound.sampled.DataLine; 19 | import javax.sound.sampled.SourceDataLine; 20 | 21 | /** 22 | * An interface to the java sound system 23 | * 24 | * @author Steven R. Brandt 25 | */ 26 | public final class ReusableClip { 27 | 28 | byte[] buf; 29 | SourceDataLine sourceLine; 30 | 31 | static Thread thread; 32 | static boolean running = false; 33 | static LinkedList queue = new LinkedList<>(); 34 | public static boolean verbose = false; 35 | 36 | static ExecutorService overlappingSoundPool = Executors.newFixedThreadPool(3); 37 | 38 | static { 39 | thread = new Thread(() -> { 40 | }); 41 | thread.start(); 42 | } 43 | 44 | private static synchronized ReusableClip dequeue() { 45 | if (queue.size() == 0) { 46 | return null; 47 | } else { 48 | return queue.removeLast(); 49 | } 50 | } 51 | 52 | private static synchronized void done() { 53 | running = false; 54 | } 55 | 56 | private static synchronized void enqueue(ReusableClip r) { 57 | queue.addFirst(r); 58 | if (!running) { 59 | try { 60 | thread.join(); 61 | } catch (InterruptedException ex) { 62 | } 63 | running = true; 64 | thread = new Thread(() -> { 65 | while (true) { 66 | ReusableClip clip = dequeue(); 67 | if (clip == null) { 68 | break; 69 | } 70 | try { 71 | clip.playNow(); 72 | if (clip.looping) { 73 | enqueue(clip); 74 | } 75 | } catch (Throwable e) { 76 | if (verbose) { 77 | e.printStackTrace(); 78 | } else { 79 | System.err.println("endclip: " + e); 80 | } 81 | } 82 | } 83 | done(); 84 | }); 85 | thread.start(); 86 | } 87 | } 88 | 89 | private static URI getURI(String name) { 90 | /* 91 | try { 92 | return ReusableClip.class.getResource(name).toURI(); 93 | } catch (URISyntaxException ex) { 94 | return null; 95 | } 96 | */ 97 | URL src = null; 98 | try { 99 | src = new URL(name); 100 | } catch (MalformedURLException me) { 101 | ; 102 | } 103 | if (src == null) { 104 | src = ReusableClip.class.getResource(name); 105 | } 106 | if (src == null) { 107 | try { 108 | src = FileUtility.findFile(name).toURL(); 109 | } catch (MalformedURLException ex) { 110 | TaskRunner.report(ex, null); 111 | } 112 | if (src == null) { 113 | new RuntimeIOException("Could not load: " + name).printStackTrace(); 114 | src = ReusableClip.class.getResource("beep.wav"); 115 | } 116 | } 117 | try { 118 | return src.toURI(); 119 | } catch (URISyntaxException e) { 120 | e.printStackTrace(); 121 | return null; 122 | } 123 | } 124 | 125 | public ReusableClip(String name) { 126 | this(getURI(name)); 127 | } 128 | final String name; 129 | 130 | public ReusableClip(URI uri) { 131 | this.name = uri == null ? "?" : uri.getPath(); 132 | try { 133 | if (verbose) { 134 | System.out.println("loading sound: " + uri); 135 | } 136 | AudioInputStream audioStream = AudioSystem.getAudioInputStream(uri.toURL()); 137 | AudioFormat audioFormat = audioStream.getFormat(); 138 | DataLine.Info info = new DataLine.Info(SourceDataLine.class, audioFormat); 139 | sourceLine = (SourceDataLine) AudioSystem.getLine(info); 140 | sourceLine.open(audioFormat); 141 | long nbytes = audioStream.getFrameLength(); 142 | while (nbytes % 4 != 0) { 143 | nbytes++; 144 | } 145 | buf = new byte[(int) nbytes]; 146 | audioStream.read(buf); 147 | } catch (Exception ex) { 148 | if (verbose) { 149 | ex.printStackTrace(); 150 | } else { 151 | System.err.println(ex); 152 | } 153 | } 154 | } 155 | 156 | public void playNow() { 157 | if (verbose) { 158 | System.out.println("playing sound: " + name); 159 | } 160 | sourceLine.start(); 161 | sourceLine.write(buf, 0, buf.length); 162 | sourceLine.drain(); 163 | sourceLine.flush(); 164 | } 165 | 166 | public void playOverlapping() { 167 | overlappingSoundPool.submit(this::playNow); 168 | } 169 | 170 | public synchronized void play() { 171 | looping = false; 172 | enqueue(this); 173 | } 174 | 175 | volatile boolean looping = false; 176 | 177 | public synchronized void loop() { 178 | looping = true; 179 | enqueue(this); 180 | } 181 | 182 | public void stop() { 183 | looping = false; 184 | } 185 | 186 | public static void testOverlapping(ReusableClip clip1, ReusableClip clip2) { 187 | clip1.playOverlapping(); 188 | clip2.playOverlapping(); 189 | } 190 | 191 | public static void main(String[] args) throws Exception { 192 | // It won't play without a JFrame. 193 | verbose = true; 194 | BasicFrame bf = new BasicFrame("title"); 195 | bf.show(); 196 | ReusableClip clip1 = new ReusableClip("arrow.wav"); 197 | ReusableClip clip2 = new ReusableClip("beep.wav"); 198 | long t1 = System.currentTimeMillis(); 199 | clip1.loop(); 200 | clip2.loop(); 201 | Thread.sleep(5000); 202 | clip1.stop(); 203 | clip2.stop(); 204 | long t2 = System.currentTimeMillis(); 205 | System.out.printf("time=%d%n", (t2 - t1)); 206 | Thread.sleep(5000); 207 | testOverlapping(clip1, clip2); 208 | bf.dispose(); 209 | } 210 | } 211 | -------------------------------------------------------------------------------- /src/basicgraphics/BasicLayout.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Click nbfs://nbhost/SystemFileSystem/Templates/Licenses/license-default.txt to change this license 3 | * Click nbfs://nbhost/SystemFileSystem/Templates/Classes/Class.java to edit this template 4 | */ 5 | package basicgraphics; 6 | 7 | import java.awt.Component; 8 | import java.awt.Container; 9 | import java.awt.Dimension; 10 | import java.awt.LayoutManager; 11 | import java.util.HashMap; 12 | import java.util.Iterator; 13 | import java.util.Map; 14 | import java.util.regex.Matcher; 15 | import java.util.regex.Pattern; 16 | import javax.swing.BorderFactory; 17 | import javax.swing.JFrame; 18 | import javax.swing.JLabel; 19 | import javax.swing.SwingConstants; 20 | 21 | /** 22 | * 23 | * @author steve 24 | */ 25 | public class BasicLayout implements LayoutManager { 26 | Map map = new HashMap<>(); 27 | Pattern pattern = Pattern.compile("x=(\\d+),y=(\\d+),w=(\\d+),h=(\\d+)"); 28 | 29 | @Override 30 | public void addLayoutComponent(String name, Component comp) { 31 | Matcher matcher = pattern.matcher(name); 32 | boolean worked = matcher.matches(); 33 | assert worked : "String does not match pattern: '"+name+"'"; 34 | int x = Integer.parseInt(matcher.group(1)); 35 | int y = Integer.parseInt(matcher.group(2)); 36 | int w = Integer.parseInt(matcher.group(3)); 37 | int h = Integer.parseInt(matcher.group(4)); 38 | assert x >= 0; 39 | assert y >= 0; 40 | assert w > 0; 41 | assert h > 0; 42 | GridDim gd = new GridDim(x,y,w,h); 43 | for(var gd2 : map.keySet()) { 44 | if(gd.overlaps(gd2)) { 45 | throw new GuiException("Overlapping boxes: "+gd+" and "+gd2); 46 | } 47 | } 48 | map.put(gd, comp); 49 | } 50 | 51 | static class GridDim { 52 | final int x,y,w,h; 53 | public int hashCode() { return x+y+w+h; } 54 | public boolean equals(Object o) { 55 | GridDim that = (GridDim)o; 56 | return this.x==that.x && this.y==that.y && this.w==that.w && this.h==that.h; 57 | } 58 | GridDim(int x,int y,int w,int h) { this.x=x; this.y=y; this.w=w; this.h=h; } 59 | public boolean overlaps(GridDim gd) { 60 | int p1 = Math.min(x, gd.x); 61 | int p2 = Math.max(x+w, gd.x+gd.w); 62 | if(p2 - p1 >= w + gd.w) return false; 63 | int k1 = Math.min(y, gd.y); 64 | int k2 = Math.max(y+h, gd.y+gd.h); 65 | if(k2 - k1 >= h + gd.h) return false; 66 | return true; 67 | } 68 | public String toString() { 69 | return "x="+x+",y="+y+",w="+w+",h="+h; 70 | } 71 | } 72 | GridDim getGridDim() { 73 | int w=0, h=0; 74 | for(Map.Entry entry : map.entrySet()) { 75 | GridDim k = entry.getKey(); 76 | int wn = k.x + k.w; 77 | int hn = k.y + k.h; 78 | if(wn > w) w = wn; 79 | if(hn > h) h = hn; 80 | } 81 | return new GridDim(0,0,w,h); 82 | } 83 | 84 | GridDim[][] gmap; 85 | public void checkGridDim() { 86 | GridDim gd = getGridDim(); 87 | gmap = new GridDim[gd.w][gd.h]; 88 | for(Map.Entry e : map.entrySet()) { 89 | GridDim k = e.getKey(); 90 | for(int i=k.x;i < k.x+k.w;i++) { 91 | for(int j=k.y;j < k.y+k.h;j++) { 92 | assert gmap[i][j] == null : String.format("i=%d,j=%d is doubly covered",i,j); 93 | gmap[i][j] = k; 94 | } 95 | } 96 | } 97 | for(int i=0;i> iter = map.entrySet().iterator(); 107 | while(iter.hasNext()) { 108 | Map.Entry entry = iter.next(); 109 | if(entry.getValue() == comp) { 110 | iter.remove(); 111 | } 112 | } 113 | } 114 | 115 | @Override 116 | public Dimension preferredLayoutSize(Container parent) { 117 | checkGridDim(); 118 | return getSize(true); 119 | } 120 | 121 | @Override 122 | public Dimension minimumLayoutSize(Container parent) { 123 | checkGridDim(); 124 | return getSize(false); 125 | } 126 | 127 | Dimension getSize(Component c,boolean preferred) { 128 | if(preferred) return c.getPreferredSize(); 129 | else return c.getMinimumSize(); 130 | } 131 | Dimension getSize(boolean preferred) { 132 | int maxh = 0, maxw = 0; 133 | GridDim gd = getGridDim(); 134 | for(Map.Entry entry : map.entrySet()) { 135 | GridDim k = entry.getKey(); 136 | Component v = entry.getValue(); 137 | Dimension d = getSize(v, preferred); 138 | int wsz = (int)Math.ceil(d.width*1.0*gd.w/k.w); 139 | int hsz = (int)Math.ceil(d.height*1.0*gd.h/k.h); 140 | if(wsz > maxw) maxw = wsz; 141 | if(hsz > maxh) maxh = hsz; 142 | } 143 | return new Dimension(maxw, maxh); 144 | } 145 | 146 | @Override 147 | public void layoutContainer(Container parent) { 148 | Dimension dim = parent.getSize(); 149 | GridDim gd = getGridDim(); 150 | double facx = dim.width*1.0/gd.w; 151 | double facy = dim.height*1.0/gd.h; 152 | for(Map.Entry entry : map.entrySet()) { 153 | GridDim k = entry.getKey(); 154 | Component v = entry.getValue(); 155 | int xpos = (int) Math.ceil(k.x*facx); 156 | int ypos = (int) Math.ceil(k.y*facy); 157 | int width = (int) Math.ceil(k.w*facx); 158 | int height = (int) Math.ceil(k.h*facy); 159 | v.setBounds(xpos, ypos, width, height); 160 | } 161 | } 162 | 163 | static JLabel mkLabel(String text) { 164 | JLabel jl = new JLabel(text); 165 | jl.setHorizontalAlignment(SwingConstants.CENTER); 166 | jl.setVerticalAlignment(SwingConstants.CENTER); 167 | jl.setBorder(BorderFactory.createEtchedBorder()); 168 | return jl; 169 | } 170 | 171 | public static void main(String[] args) { 172 | JFrame jf = new JFrame(); 173 | Container c = jf.getContentPane(); 174 | c.setLayout(new BasicLayout()); 175 | c.add("x=0,y=0,w=1,h=1", mkLabel("Upper left")); 176 | c.add("x=1,y=0,w=1,h=1", mkLabel("Upper right")); 177 | c.add("x=0,y=1,w=2,h=2", mkLabel("The bottom")); 178 | c.add("x=2,y=0,w=1,h=3", mkLabel("Edge")); 179 | c.add("x=0,y=3,w=3,h=1", mkLabel("Very Bottom")); 180 | jf.pack(); 181 | jf.setVisible(true); 182 | } 183 | } 184 | -------------------------------------------------------------------------------- /src/basicgraphics/examples/BasicGraphics.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this license header, choose License Headers in Project Properties. 3 | * To change this template file, choose Tools | Templates 4 | * and open the template in the editor. 5 | */ 6 | package basicgraphics.examples; 7 | 8 | import basicgraphics.BasicFrame; 9 | import basicgraphics.ClockWorker; 10 | import basicgraphics.CollisionEventType; 11 | import basicgraphics.Scene; 12 | import basicgraphics.Sprite; 13 | import basicgraphics.SpriteCollisionEvent; 14 | import basicgraphics.SpriteComponent; 15 | import basicgraphics.SpriteSpriteCollisionListener; 16 | import basicgraphics.Task; 17 | import basicgraphics.images.Picture; 18 | import java.awt.Color; 19 | import java.awt.Dimension; 20 | import java.awt.Graphics; 21 | import java.awt.Image; 22 | import java.awt.event.ActionEvent; 23 | import java.awt.event.ActionListener; 24 | import java.awt.event.KeyEvent; 25 | import java.awt.event.KeyListener; 26 | import java.awt.event.MouseEvent; 27 | import java.awt.event.MouseListener; 28 | import java.util.Random; 29 | import javax.swing.JButton; 30 | import javax.swing.JLabel; 31 | import javax.swing.JOptionPane; 32 | 33 | /** 34 | * 35 | * @author sbrandt 36 | */ 37 | public class BasicGraphics { 38 | 39 | public final static int DIE_AFTER = 300; 40 | 41 | final static int nballs = 30; 42 | final static int ballSize = 20; 43 | 44 | 45 | static Picture createBall(Color color) { 46 | Image im1 = BasicFrame.createImage(ballSize, ballSize); 47 | Graphics imgr = im1.getGraphics(); 48 | imgr.setColor(color); 49 | imgr.fillOval(0, 0, ballSize, ballSize); 50 | Picture p = new Picture(im1).transparentBright(); 51 | return p; 52 | } 53 | final static Picture orangeBall = createBall(Color.orange); 54 | final static Picture blueBall = createBall(Color.blue); 55 | final static Picture greenBall = createBall(Color.green); 56 | final static Picture redBall = createBall(Color.red); 57 | 58 | static class Ball extends Sprite { 59 | boolean dead = false; 60 | 61 | Ball(Scene sc) { 62 | super(sc); 63 | } 64 | 65 | @Override 66 | public void mouseClicked(MouseEvent me) { 67 | setPicture(orangeBall); 68 | if(dead) { 69 | dead = false; 70 | setVel(getVelX()*2, getVelY()*2); 71 | } 72 | } 73 | 74 | @Override 75 | public void processEvent(SpriteCollisionEvent ce) { 76 | if (ce.eventType == CollisionEventType.WALL) { 77 | if (ce.xlo) { 78 | setVel(Math.abs(getVelX()), getVelY()); 79 | } 80 | if (ce.xhi) { 81 | setVel(-Math.abs(getVelX()), getVelY()); 82 | } 83 | if (ce.ylo) { 84 | setVel(getVelX(), Math.abs(getVelY())); 85 | } 86 | if (ce.yhi) { 87 | setVel(getVelX(), -Math.abs(getVelY())); 88 | } 89 | } 90 | } 91 | } 92 | 93 | static String[][] layout = { 94 | {"topl", "topm", "topr"}, 95 | {"row2", "row2", "row2"}, 96 | {"row3", "row3", "row3"}, 97 | {"row4", "row4", "botr"} 98 | }; 99 | 100 | /** 101 | * @param args the command line arguments 102 | */ 103 | public static void main(String[] args) { 104 | BasicFrame f = new BasicFrame("Fish"); 105 | SpriteComponent sc = new SpriteComponent(); 106 | final JButton button1 = new JButton("Button 1"); 107 | button1.addActionListener(new ActionListener() { 108 | @Override 109 | public void actionPerformed(ActionEvent e) { 110 | JOptionPane.showMessageDialog(button1, "Button 1 was pressed!"); 111 | } 112 | }); 113 | button1.addActionListener(new Foo()); 114 | f.setStringLayout(layout); 115 | f.add("topl", button1); 116 | f.add("topm", new JButton("Button 2")); 117 | f.add("topr", new JButton("Button 3")); 118 | f.add("row2", new JLabel("Row 2")); 119 | f.add("row4", new Picture("sarah.png").makeButton()); 120 | f.add("botr", new JLabel("corner", JLabel.CENTER)); 121 | 122 | Bat bat = new Bat(sc.getScene()); 123 | 124 | Dimension d = new Dimension(800, 400); 125 | sc.setPreferredSize(d); 126 | 127 | Random rand = new Random(); 128 | KeyListener kl = new KeyListener() { 129 | @Override 130 | public void keyTyped(KeyEvent e) { 131 | } 132 | 133 | @Override 134 | public void keyPressed(KeyEvent e) { 135 | System.out.println("pressed: " + e.toString()); 136 | } 137 | 138 | @Override 139 | public void keyReleased(KeyEvent e) { 140 | } 141 | }; 142 | f.addKeyListener(kl); 143 | MouseListener ml = new MouseListener() { 144 | @Override 145 | public void mouseClicked(MouseEvent e) { 146 | System.out.println("click"); 147 | } 148 | 149 | @Override 150 | public void mousePressed(MouseEvent e) { 151 | } 152 | 153 | @Override 154 | public void mouseReleased(MouseEvent e) { 155 | } 156 | 157 | @Override 158 | public void mouseEntered(MouseEvent e) { 159 | } 160 | 161 | @Override 162 | public void mouseExited(MouseEvent e) { 163 | } 164 | }; 165 | sc.addMouseListener(ml); 166 | for (int i = 0; i < nballs; i++) { 167 | Ball sball = new Ball(sc.getScene()); 168 | if (i % 2 == 0) { 169 | sball.setPicture(redBall); 170 | } else { 171 | sball.setPicture(greenBall); 172 | } 173 | sball.setVel(2 * rand.nextDouble() - 1, 2 * rand.nextDouble() -1); 174 | sball.setX(rand.nextInt(d.width)); 175 | sball.setY(rand.nextInt(d.height)); 176 | } 177 | 178 | sc.addSpriteSpriteCollisionListener(Ball.class,Ball.class,new SpriteSpriteCollisionListener() { 179 | @Override 180 | public void collision(Ball sp1, Ball sp2) { 181 | double vx = sp1.getVelX(); 182 | double vy = sp1.getVelY(); 183 | sp1.setVel(sp2.getVelX(), sp2.getVelY()); 184 | sp2.setVel(vx, vy); 185 | } 186 | }); 187 | sc.addSpriteSpriteCollisionListener(Ball.class, Bat.class, new SpriteSpriteCollisionListener() { 188 | @Override 189 | public void collision(Ball sp1, Bat sp2) { 190 | if(sp1.dead) return; 191 | sp1.dead = true; 192 | sp1.setVel(sp1.getVelX()/2, sp1.getVelY()/2); 193 | sp1.setPicture(blueBall); 194 | ClockWorker.addTask(new Task(DIE_AFTER) { 195 | public void run() { 196 | if (iteration() == DIE_AFTER) { 197 | if(sp1.dead) sp1.destroy(); 198 | } 199 | } 200 | }); 201 | //Clock.addTask(new DeathTimer(DIE_AFTER,sp1)); 202 | } 203 | }); 204 | 205 | ClockWorker.initialize(20); 206 | ClockWorker.addTask(sc.moveSprites()); 207 | 208 | f.add("row3", sc); 209 | f.show(); 210 | } 211 | 212 | } 213 | -------------------------------------------------------------------------------- /src/basicgraphics/examples/BasicGraphics2.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this license header, choose License Headers in Project Properties. 3 | * To change this template file, choose Tools | Templates 4 | * and open the template in the editor. 5 | */ 6 | package basicgraphics.examples; 7 | 8 | import basicgraphics.BasicFrame; 9 | import basicgraphics.BasicLayout; 10 | import basicgraphics.ClockWorker; 11 | import basicgraphics.CollisionEventType; 12 | import basicgraphics.Scene; 13 | import basicgraphics.Sprite; 14 | import basicgraphics.SpriteCollisionEvent; 15 | import basicgraphics.SpriteComponent; 16 | import basicgraphics.SpriteSpriteCollisionListener; 17 | import basicgraphics.Task; 18 | import basicgraphics.images.Picture; 19 | import java.awt.Color; 20 | import java.awt.Dimension; 21 | import java.awt.Graphics; 22 | import java.awt.Image; 23 | import java.awt.event.ActionEvent; 24 | import java.awt.event.ActionListener; 25 | import java.awt.event.KeyEvent; 26 | import java.awt.event.KeyListener; 27 | import java.awt.event.MouseEvent; 28 | import java.awt.event.MouseListener; 29 | import java.util.Random; 30 | import javax.swing.JButton; 31 | import javax.swing.JLabel; 32 | import javax.swing.JOptionPane; 33 | 34 | /** 35 | * 36 | * @author sbrandt 37 | */ 38 | public class BasicGraphics2 { 39 | 40 | public final static int DIE_AFTER = 300; 41 | 42 | final static int nballs = 30; 43 | final static int ballSize = 20; 44 | 45 | 46 | static Picture createBall(Color color) { 47 | Image im1 = BasicFrame.createImage(ballSize, ballSize); 48 | Graphics imgr = im1.getGraphics(); 49 | imgr.setColor(color); 50 | imgr.fillOval(0, 0, ballSize, ballSize); 51 | Picture p = new Picture(im1).transparentBright(); 52 | return p; 53 | } 54 | final static Picture orangeBall = createBall(Color.orange); 55 | final static Picture blueBall = createBall(Color.blue); 56 | final static Picture greenBall = createBall(Color.green); 57 | final static Picture redBall = createBall(Color.red); 58 | 59 | static class Ball extends Sprite { 60 | boolean dead = false; 61 | 62 | Ball(Scene sc) { 63 | super(sc); 64 | } 65 | 66 | @Override 67 | public void mouseClicked(MouseEvent me) { 68 | setPicture(orangeBall); 69 | if(dead) { 70 | dead = false; 71 | setVel(getVelX()*2, getVelY()*2); 72 | } 73 | } 74 | 75 | @Override 76 | public void processEvent(SpriteCollisionEvent ce) { 77 | if (ce.eventType == CollisionEventType.WALL) { 78 | if (ce.xlo) { 79 | setVel(Math.abs(getVelX()), getVelY()); 80 | } 81 | if (ce.xhi) { 82 | setVel(-Math.abs(getVelX()), getVelY()); 83 | } 84 | if (ce.ylo) { 85 | setVel(getVelX(), Math.abs(getVelY())); 86 | } 87 | if (ce.yhi) { 88 | setVel(getVelX(), -Math.abs(getVelY())); 89 | } 90 | } 91 | } 92 | } 93 | 94 | static String[][] layout = { 95 | {"topl", "topm", "topr"}, 96 | {"row2", "row2", "row2"}, 97 | {"row3", "row3", "row3"}, 98 | {"row4", "row4", "botr"} 99 | }; 100 | 101 | /** 102 | * @param args the command line arguments 103 | */ 104 | public static void main(String[] args) { 105 | BasicFrame f = new BasicFrame("Fish"); 106 | SpriteComponent sc = new SpriteComponent(); 107 | final JButton button1 = new JButton("Button 1"); 108 | button1.addActionListener(new ActionListener() { 109 | @Override 110 | public void actionPerformed(ActionEvent e) { 111 | JOptionPane.showMessageDialog(button1, "Button 1 was pressed!"); 112 | } 113 | }); 114 | button1.addActionListener(new Foo()); 115 | BasicLayout blayout = new BasicLayout(); 116 | f.setLayout(blayout); 117 | f.add("x=0,y=0,w=1,h=1", button1); 118 | f.add("x=1,y=0,w=1,h=1", new JButton("Button 2")); 119 | f.add("x=2,y=0,w=1,h=1", new JButton("Button 3")); 120 | f.add("x=0,y=1,w=3,h=1", new JLabel("Row 2")); 121 | f.add("x=0,y=5,w=2,h=1", new Picture("sarah.png").makeButton()); 122 | f.add("x=2,y=5,w=1,h=1", new JLabel("corner", JLabel.CENTER)); 123 | 124 | Bat bat = new Bat(sc.getScene()); 125 | 126 | Dimension d = new Dimension(800, 400); 127 | sc.setPreferredSize(d); 128 | 129 | Random rand = new Random(); 130 | KeyListener kl = new KeyListener() { 131 | @Override 132 | public void keyTyped(KeyEvent e) { 133 | } 134 | 135 | @Override 136 | public void keyPressed(KeyEvent e) { 137 | System.out.println("pressed: " + e.toString()); 138 | } 139 | 140 | @Override 141 | public void keyReleased(KeyEvent e) { 142 | } 143 | }; 144 | f.addKeyListener(kl); 145 | MouseListener ml = new MouseListener() { 146 | @Override 147 | public void mouseClicked(MouseEvent e) { 148 | System.out.println("click"); 149 | } 150 | 151 | @Override 152 | public void mousePressed(MouseEvent e) { 153 | } 154 | 155 | @Override 156 | public void mouseReleased(MouseEvent e) { 157 | } 158 | 159 | @Override 160 | public void mouseEntered(MouseEvent e) { 161 | } 162 | 163 | @Override 164 | public void mouseExited(MouseEvent e) { 165 | } 166 | }; 167 | sc.addMouseListener(ml); 168 | for (int i = 0; i < nballs; i++) { 169 | Ball sball = new Ball(sc.getScene()); 170 | if (i % 2 == 0) { 171 | sball.setPicture(redBall); 172 | } else { 173 | sball.setPicture(greenBall); 174 | } 175 | sball.setVel(2 * rand.nextDouble() - 1, 2 * rand.nextDouble() -1); 176 | sball.setX(rand.nextInt(d.width)); 177 | sball.setY(rand.nextInt(d.height)); 178 | } 179 | 180 | sc.addSpriteSpriteCollisionListener(Ball.class,Ball.class,new SpriteSpriteCollisionListener() { 181 | @Override 182 | public void collision(Ball sp1, Ball sp2) { 183 | double vx = sp1.getVelX(); 184 | double vy = sp1.getVelY(); 185 | sp1.setVel(sp2.getVelX(), sp2.getVelY()); 186 | sp2.setVel(vx, vy); 187 | } 188 | }); 189 | sc.addSpriteSpriteCollisionListener(Ball.class, Bat.class, new SpriteSpriteCollisionListener() { 190 | @Override 191 | public void collision(Ball sp1, Bat sp2) { 192 | if(sp1.dead) return; 193 | sp1.dead = true; 194 | sp1.setVel(sp1.getVelX()/2, sp1.getVelY()/2); 195 | sp1.setPicture(blueBall); 196 | ClockWorker.addTask(new Task(DIE_AFTER) { 197 | public void run() { 198 | if (iteration() == DIE_AFTER) { 199 | if(sp1.dead) sp1.destroy(); 200 | } 201 | } 202 | }); 203 | //Clock.addTask(new DeathTimer(DIE_AFTER,sp1)); 204 | } 205 | }); 206 | 207 | ClockWorker.initialize(20); 208 | ClockWorker.addTask(sc.moveSprites()); 209 | 210 | f.add("x=0,y=2,w=3,h=3", sc); 211 | f.show(); 212 | } 213 | 214 | } -------------------------------------------------------------------------------- /src/basicgraphics/images/Picture.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this license header, choose License Headers in Project Properties. 3 | * To change this template file, choose Tools | Templates 4 | * and open the template in the editor. 5 | */ 6 | package basicgraphics.images; 7 | 8 | import basicgraphics.BasicFrame; 9 | import basicgraphics.FileUtility; 10 | import basicgraphics.TaskRunner; 11 | import java.awt.Color; 12 | import java.awt.Dimension; 13 | import java.awt.Graphics; 14 | import java.awt.Graphics2D; 15 | import java.awt.Image; 16 | import java.awt.geom.AffineTransform; 17 | import java.awt.image.BufferedImage; 18 | import java.net.MalformedURLException; 19 | import java.net.URI; 20 | import java.util.HashSet; 21 | import java.util.Random; 22 | import java.util.Set; 23 | import java.util.Map; 24 | import java.util.HashMap; 25 | import javax.imageio.ImageIO; 26 | import javax.swing.ImageIcon; 27 | import javax.swing.JButton; 28 | import javax.swing.JComponent; 29 | 30 | /** 31 | * This class encapsulates the creation and use of images. 32 | * 33 | * @author sbrandt 34 | */ 35 | public class Picture extends JComponent { 36 | 37 | private BufferedImage image; 38 | private int width, height; 39 | 40 | @Override 41 | public Dimension getSize() { 42 | return new Dimension(width, height); 43 | } 44 | 45 | BufferedImage addAlpha(BufferedImage bi) { 46 | BufferedImage newbi = BasicFrame.createImage(bi.getWidth(), bi.getHeight()); 47 | Graphics2D g = newbi.createGraphics(); 48 | g.drawImage(bi, 0, 0, null); 49 | return newbi; 50 | } 51 | 52 | /** 53 | * Set all white pixels to transparent 54 | */ 55 | public Picture transparentBright() { 56 | BufferedImage newImage = addAlpha(image); 57 | for (int j = 0; j < height; j++) { 58 | for (int i = 0; i < width; i++) { 59 | int color = image.getRGB(i, j); 60 | if ((color & 0x00FFFFFF) == 0x00FFFFFF) { 61 | newImage.setRGB(i, j, 0x00FFFFFF); 62 | } 63 | } 64 | } 65 | return new Picture(newImage); 66 | } 67 | public Picture transparentBright(int brightness) { 68 | BufferedImage newImage = addAlpha(image); 69 | for (int j = 0; j < height; j++) { 70 | for (int i = 0; i < width; i++) { 71 | int color = image.getRGB(i, j); 72 | int br = getBrightness(color); 73 | if (br >= brightness) { 74 | newImage.setRGB(i, j, 0x00FFFFFF); 75 | } 76 | } 77 | } 78 | return new Picture(newImage); 79 | } 80 | 81 | private int getBrightness(int color) { 82 | int r = (color >> 16) & 0xFF; 83 | int g = (color >> 8) & 0xFF; 84 | int b = color & 0xFF; 85 | return Math.min(Math.min(r,g),b); 86 | } 87 | 88 | /** 89 | * Set all colors found on the border of the image to transparent 90 | */ 91 | public Picture transparentBorder() { 92 | BufferedImage newImage = addAlpha(image); 93 | Set set = new HashSet<>(); 94 | for (int j = 0; j < height; j++) { 95 | int value = image.getRGB(0, j) & 0x00FFFFFF; 96 | set.add(value); 97 | value = image.getRGB(width - 1, j) & 0x00FFFFFF; 98 | set.add(value); 99 | } 100 | for (int i = 0; i < width; i++) { 101 | int value = image.getRGB(i, 0) & 0x00FFFFFF; 102 | set.add(value); 103 | value = image.getRGB(i, height - 1) & 0x00FFFFFF; 104 | set.add(value); 105 | } 106 | int count = 0; 107 | for (int j = 0; j < height; j++) { 108 | for (int i = 0; i < width; i++) { 109 | int color = image.getRGB(i, j) & 0x00FFFFFF; 110 | if (set.contains(color)) { 111 | newImage.setRGB(i, j, color); 112 | count++; 113 | } 114 | } 115 | } 116 | return new Picture(newImage); 117 | } 118 | 119 | public void makeSquare() { 120 | if (width == height) { 121 | return; 122 | } 123 | int w = width > height ? width : height; 124 | int zero = image.getRGB(0, 0); 125 | BufferedImage bi = BasicFrame.createImage(w, w); 126 | for (int j = 0; j < w; j++) { 127 | for (int i = 0; i < w; i++) { 128 | bi.setRGB(i, j, zero); 129 | } 130 | } 131 | for (int j = 0; j < height; j++) { 132 | for (int i = 0; i < width; i++) { 133 | int color = image.getRGB(i, j); 134 | int i2 = i, j2 = j; 135 | if (width < w) { 136 | i2 += (w - width) / 2; 137 | } 138 | if (height < w) { 139 | j2 += (w - height) / 2; 140 | } 141 | bi.setRGB(i2, j2, color); 142 | } 143 | } 144 | image = bi; 145 | width = w; 146 | height = w; 147 | } 148 | 149 | public Picture shrinkToMinimum() { 150 | int lox = width, hix = 0; 151 | int loy = height, hiy = 0; 152 | for (int j = 0; j < height; j++) { 153 | for (int i = 0; i < width; i++) { 154 | int color = image.getRGB(i, j) & 0xFF000000; 155 | if (color != 0) { 156 | if (i < lox) { 157 | lox = i; 158 | } 159 | if (i > hix) { 160 | hix = i; 161 | } 162 | if (j < loy) { 163 | loy = j; 164 | } 165 | if (j > hiy) { 166 | hiy = j; 167 | } 168 | } 169 | } 170 | } 171 | if (lox == 0 && loy == 0 && hix == width - 1 && hiy == height - 1) { 172 | return this; 173 | } 174 | BufferedImage im = BasicFrame.createImage(1 + hix - lox, 1 + hiy - loy); 175 | for (int j = loy; j <= hiy; j++) { 176 | for (int i = lox; i <= hix; i++) { 177 | int color = image.getRGB(i, j); 178 | im.setRGB(i - lox, j - loy, color); 179 | } 180 | } 181 | image = im; 182 | width = (hix - lox + 1); 183 | height = (hiy - loy + 1); 184 | return new Picture(im); 185 | } 186 | 187 | /** 188 | * Get the raw image stored by this class. 189 | * 190 | * @return 191 | */ 192 | public Image getImage() { 193 | return image; 194 | } 195 | 196 | /** 197 | * You should store your images in the same directory as the source for this 198 | * class (i.e. the same directory as Picture.java). That will enable you to 199 | * load them either from the working directory in Netbeans, or in the jar 200 | * file you distribute. 201 | * 202 | * @param name 203 | */ 204 | public Picture(String name) { 205 | if(name == null) throw new NullPointerException("No name given to Picture"); 206 | if (loadedImages.containsKey(name)) { 207 | // Load from cache 208 | image = loadedImages.get(name); 209 | } else { 210 | URI src = null; 211 | try { 212 | src = new URI(name); 213 | image = ImageIO.read(src.toURL()); 214 | } catch (Exception ex) { 215 | // We don't care why this fails 216 | } 217 | if (image == null) { 218 | src = FileUtility.findFile(name); 219 | try { 220 | image = ImageIO.read(src.toURL()); 221 | } catch (MalformedURLException ex) { 222 | TaskRunner.report(ex, null); 223 | } catch (Exception ex) { 224 | TaskRunner.report(ex, null); 225 | } 226 | } 227 | if(image == null) image = randBlock(); 228 | } 229 | width = image.getWidth(); 230 | height = image.getHeight(); 231 | setPreferredSize(new Dimension(width, height)); 232 | setMinimumSize(getPreferredSize()); 233 | loadedImages.put(name, image); 234 | } 235 | static Map loadedImages = new HashMap<>(); 236 | 237 | /** 238 | * You can also create a picture from an image directly (using 239 | * basicgraphics.BasicFrame.createImage()) and drawing on it. 240 | * 241 | * @param im 242 | */ 243 | public Picture(Image im) { 244 | this.image = (BufferedImage) im; 245 | width = image.getWidth(); 246 | height = image.getHeight(); 247 | setPreferredSize(new Dimension(width, height)); 248 | setMinimumSize(getPreferredSize()); 249 | } 250 | 251 | public int getWidth() { 252 | return width; 253 | } 254 | 255 | public int getHeight() { 256 | return height; 257 | } 258 | 259 | public Picture resize(double factor) { 260 | int w = (int) (image.getWidth() * factor); 261 | int h = (int) (image.getHeight() * factor); 262 | BufferedImage bi = BasicFrame.createImage(w, h); 263 | Graphics2D g2 = (Graphics2D) bi.getGraphics(); 264 | AffineTransform xform = new AffineTransform(); 265 | xform.setToScale(factor, factor); 266 | g2.drawImage(image, xform, this); 267 | return new Picture(bi); 268 | } 269 | 270 | public Picture flipLeftRight() { 271 | int w = image.getWidth(); 272 | int h = image.getHeight(); 273 | BufferedImage bi = BasicFrame.createImage(w, h); 274 | Graphics2D g2 = (Graphics2D) bi.getGraphics(); 275 | g2.drawImage(image, w, 0, -w, h, null); 276 | return new Picture(bi); 277 | } 278 | 279 | public Picture flipUpDown() { 280 | int w = image.getWidth(); 281 | int h = image.getHeight(); 282 | BufferedImage bi = BasicFrame.createImage(w, h); 283 | Graphics2D g2 = (Graphics2D) bi.getGraphics(); 284 | g2.drawImage(image, 0, h, w, -h, null); 285 | return new Picture(bi); 286 | } 287 | 288 | /** 289 | * Create a button that uses the same image as the one stored in this 290 | * Picture. 291 | * 292 | * @return 293 | */ 294 | public JButton makeButton() { 295 | return new JButton(getIcon()); 296 | } 297 | 298 | public ImageIcon getIcon() { 299 | return new ImageIcon(image); 300 | } 301 | 302 | public boolean mask(int i, int j) { 303 | if(i < 0 || i >= width || j < 0 || j >= height) return false; 304 | int val = image.getRGB(i, j); 305 | return (val & 0xFF000000) != 0; 306 | } 307 | 308 | final static Random RAND = new Random(); 309 | 310 | private BufferedImage randBlock() { 311 | int w = 10 + RAND.nextInt(30); 312 | int h = 10 + RAND.nextInt(30); 313 | BufferedImage im = BasicFrame.createImage(w, h); 314 | int r = RAND.nextInt(256); 315 | int g = RAND.nextInt(256); 316 | int b = RAND.nextInt(256); 317 | Color c = new Color(r, g, b); 318 | Graphics gr = im.getGraphics(); 319 | gr.setColor(c); 320 | gr.fillRect(0, 0, w, h); 321 | return im; 322 | } 323 | 324 | public static void main(String[] args) { 325 | Picture p = new Picture("meleeBasicAttackL.png"); 326 | } 327 | } 328 | -------------------------------------------------------------------------------- /src/maze/Maze.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this license header, choose License Headers in Project Properties. 3 | * To change this template file, choose Tools | Templates 4 | * and open the template in the editor. 5 | */ 6 | package maze; 7 | 8 | import basicgraphics.BasicFrame; 9 | import basicgraphics.ClockWorker; 10 | import basicgraphics.Sprite; 11 | import basicgraphics.SpriteComponent; 12 | import basicgraphics.Task; 13 | import basicgraphics.images.Picture; 14 | import java.util.ArrayList; 15 | import java.util.LinkedList; 16 | import java.util.List; 17 | import java.util.Queue; 18 | import java.util.Random; 19 | import java.util.Stack; 20 | 21 | /** 22 | * The Maze class generates 23 | * @author sbrandt and knarf 24 | */ 25 | public class Maze { 26 | public static final Random RAND = new Random(); 27 | int sizex, sizey; 28 | Cell[][] board; 29 | MazeViz mv; 30 | 31 | Maze() {} 32 | Maze(MazeViz mv) { this.mv = mv; } 33 | 34 | /** 35 | * Students don't need to follow this logic 36 | * for the lab. However, they are encouraged 37 | * to trace it through on their own. 38 | * @param sx size of the maze in x 39 | * @param sy size of the maze in y 40 | */ 41 | public void initBoard(int sx, int sy) { 42 | sizex = 2*sx+1; 43 | sizey = 2*sy+1; 44 | board = new Cell[sizex][sizey]; 45 | for (int x=0; x walls = new ArrayList<>(); 54 | 55 | if (startx-1 > 0) 56 | walls.add(new Pos(startx-1, starty )); 57 | if (startx+1 < sizex-1) 58 | walls.add(new Pos(startx+1, starty )); 59 | if (starty-1 > 0) 60 | walls.add(new Pos(startx , starty-1)); 61 | if (starty+1 < sizey-1) 62 | walls.add(new Pos(startx , starty+1)); 63 | 64 | while (walls.size() > 0) { 65 | Pos cell = null; 66 | Pos wall = walls.get(RAND.nextInt(walls.size())); 67 | if (wall.x%2 == 1) { 68 | if (board[wall.x][wall.y-1].isWall) 69 | cell = new Pos(wall.x, wall.y-1); 70 | if (board[wall.x][wall.y+1].isWall) 71 | cell = new Pos(wall.x, wall.y+1); 72 | } else { 73 | if (board[wall.x-1][wall.y].isWall) 74 | cell = new Pos(wall.x-1, wall.y); 75 | if (board[wall.x+1][wall.y].isWall) 76 | cell = new Pos(wall.x+1, wall.y); 77 | } 78 | if (cell != null) { 79 | board[wall.x][wall.y].isWall = false; 80 | board[cell.x][cell.y].isWall = false; 81 | if (cell.x-1 > 0 && board[cell.x-1][cell.y ].isWall) 82 | walls.add(new Pos(cell.x-1, cell.y )); 83 | if (cell.x+1 < sizex-1 && board[cell.x+1][cell.y ].isWall) 84 | walls.add(new Pos(cell.x+1, cell.y )); 85 | if (cell.y-1 > 0 && board[cell.x ][cell.y-1].isWall) 86 | walls.add(new Pos(cell.x , cell.y-1)); 87 | if (cell.y+1 < sizey-1 && board[cell.x][cell.y+1].isWall) 88 | walls.add(new Pos(cell.x , cell.y+1)); 89 | } 90 | walls.remove(wall); 91 | } 92 | 93 | } 94 | 95 | char toChar(int n) { 96 | while(true) { 97 | if(n <= 9) 98 | return (char)(n+'0'); 99 | n -= 10; 100 | if(n <= 'z'-'a') 101 | return (char)(n+'a'); 102 | n -= ('z' - 'a' + 1); 103 | if(n <= 'Z'-'A') 104 | return (char)(n+'A'); 105 | n -= ('Z' - 'A' + 1); 106 | } 107 | } 108 | 109 | public String toString() { 110 | StringBuilder sb = new StringBuilder(); 111 | for (int y=0; y 0) 116 | sb.append("."+toChar(board[x][y].sequence)); 117 | else if (board[x][y].isStart) 118 | sb.append(".!"); 119 | else if (board[x][y].isGoal) 120 | sb.append(".!"); 121 | else 122 | sb.append(".."); 123 | } 124 | sb.append("\n"); 125 | } 126 | return sb.toString(); 127 | } 128 | 129 | public Stack solveAnim(final PathFinder m) { 130 | // Start from upper left corner and try to get to lower right corner 131 | Pos start = new Pos(1,1); 132 | final Pos goal = new Pos(sizex-2, sizey-2); 133 | // Make sure these positions are not walls 134 | assert !board[start.x][start.y].isWall; 135 | assert !board[goal.x] [goal.y].isWall; 136 | 137 | board[start.x][start.y].isStart = true; 138 | board[goal.x][goal.y].isGoal = true; 139 | 140 | final Stack s = new Stack<>(); 141 | 142 | // Put positions we need to continue to search from in a queue 143 | final Queue toSearch = new LinkedList<>(); 144 | // We need to start searching from the start position 145 | toSearch.add(start); 146 | // Mark the start position on the board (as already searched) 147 | board[start.x][start.y].sequence=1; 148 | Sprite sp = new Sprite(mv.jp.getScene()) { 149 | int step = 0; 150 | // Constructor for anonymous 151 | // inner class 152 | { 153 | setX(-100); 154 | // This "sprite" doesn't really display, it just 155 | // uses the timer. Create a 1x1 image and put it 156 | // offscreen. 157 | setPicture(new Picture(BasicFrame.createImage(1, 1))); 158 | 159 | ClockWorker.addTask(new Task() { 160 | @Override 161 | public void run() { 162 | doMove(); 163 | } 164 | }); 165 | } 166 | /** 167 | * Step through the algorithm to find the shortest path. 168 | */ 169 | public void doMove() { 170 | if(step == 0) { 171 | if(!m.tracePath(board, toSearch)) 172 | step=1; 173 | } else if(step == 1) { 174 | m.retracePath(goal, board, s); 175 | clear(); 176 | step = 2; 177 | } else if(step >= 2 && step - 2 < s.size()) { 178 | Pos p = s.get(step-2); 179 | step++; 180 | board[p.x][p.y].sequence = s.size() - (step - 2)+1; 181 | } 182 | } 183 | }; 184 | // mv.jp.addSprite(sp); 185 | // mv.jp.start(0, 100); 186 | mv.initMaze(this); 187 | ClockWorker.addTask(mv.jp.moveSprites()); 188 | System.out.println("Got here"); 189 | return s; 190 | } 191 | public Stack solve(PathFinder m) { 192 | // Start from upper left corner and try to get to lower right corner 193 | Pos start = new Pos(1,1); 194 | Pos goal = new Pos(sizex-2, sizey-2); 195 | // Make sure these positions are not walls 196 | assert !board[start.x][start.y].isWall; 197 | assert !board[goal.x] [goal.y].isWall; 198 | 199 | board[start.x][start.y].isStart = true; 200 | board[goal.x][goal.y].isGoal = true; 201 | 202 | // Put positions we need to continue to search from in a queue 203 | Queue toSearch = new LinkedList<>(); 204 | // We need to start searching from the start position 205 | toSearch.add(start); 206 | // Mark the start position on the board (as already searched) 207 | board[start.x][start.y].sequence=1; 208 | 209 | int chk_size = sizex; 210 | if(sizey > sizex) chk_size = sizey; 211 | chk_size /= 3; 212 | for(int n=2;n= sizeBefore : 218 | "The queue should not shrink in addPathElement()"; 219 | LinkedList ll = (LinkedList) toSearch; 220 | for (int i = sizeBefore; i < sizeAfter; i++) { 221 | Pos p = ll.get(i); 222 | Cell c = board[p.x][p.y]; 223 | assert minc(p) : "Bad value for sequence in cell at "+p; 224 | } 225 | } 226 | 227 | while(true) { 228 | boolean b2 = !toSearch.isEmpty(); 229 | boolean b = m.tracePath(board,toSearch); 230 | assert b == b2 : "tracePath() returned the wrong value"; 231 | if(!b) 232 | break; 233 | } 234 | 235 | Stack s = new Stack<>(); 236 | m.retracePath(goal,board,s); 237 | int cval = s.size(); 238 | for(Pos p : s) { 239 | Cell c = board[p.x][p.y]; 240 | assert c.sequence == cval : "Bad sequence in answer: "+c.sequence+" != "+cval; 241 | assert minc(p) : "bad predecessor for "+c.sequence+" pos="+p; 242 | if(c.sequence == 1) assert c.isStart; 243 | if(c.sequence == s.size()) assert c.isGoal; 244 | cval--; 245 | } 246 | int n = s.size(); 247 | for(Pos p : s) { 248 | assert board[p.x][p.y].sequence == n--; 249 | } 250 | int req = board.length + board[0].length - 5; 251 | assert s.size() >= req : "Too few elements in solution: "+s.size()+" < "+req; 252 | Pos pstart = s.get(s.size()-1); 253 | assert board[pstart.x][pstart.y].isStart == true; 254 | assert board[pstart.x][pstart.y].sequence > 0; 255 | Pos pgoal = s.get(0); 256 | assert board[pgoal.x][pgoal.y].isGoal == true; 257 | assert board[pgoal.x][pgoal.y].sequence > 0; 258 | clear(); 259 | n = s.size(); 260 | for(Pos p : s) { 261 | board[p.x][p.y].sequence = n--; 262 | } 263 | return s; 264 | } 265 | 266 | public void clear() { 267 | for(int i=0;i { 23 | 24 | private Scene scene; 25 | private boolean added = false; 26 | private double headingOffset=0, heading=0; 27 | public boolean freezeOrientation = false; 28 | 29 | private Sprite() {} 30 | public Sprite(Scene sc) { 31 | scene = sc; 32 | assert sc != null; 33 | //sc.addSprite(this); 34 | } 35 | 36 | public SpriteComponent getSpriteComponent() { 37 | return scene.spritecomponent; 38 | } 39 | 40 | public boolean is_visible = true; 41 | 42 | /** 43 | * @return the x-coordinate of the center of the image 44 | */ 45 | public double centerX() { 46 | return getX()+getWidth()/2; 47 | } 48 | /** 49 | * @return the y-coordinate of the center of the image 50 | */ 51 | public double centerY() { 52 | return getY()+getHeight()/2; 53 | } 54 | public double collisionBufferFactor = 1.0; 55 | /** 56 | * @return the x-coordinate of the left side of the image 57 | */ 58 | public double left() { 59 | return centerX()-collisionBufferFactor*getWidth()/2; 60 | } 61 | /** 62 | * @return the x-coordinate of the right side of the image 63 | */ 64 | public double right() { 65 | return centerX()+collisionBufferFactor*getWidth()/2; 66 | } 67 | /** 68 | * @return the y-coordinate of the top of the image. 69 | */ 70 | public double top() { 71 | return centerY()-collisionBufferFactor*getHeight()/2; 72 | } 73 | /** 74 | * @return the y-coordinate of the bottom of the image. 75 | */ 76 | public double bottom() { 77 | return centerY()+collisionBufferFactor*getHeight()/2; 78 | } 79 | 80 | static boolean overlapx(Sprite sp1,Sprite sp2) { 81 | return sp1.left() <= sp2.right() && sp1.right() >= sp2.left(); 82 | } 83 | 84 | static boolean overlapy(Sprite sp1,Sprite sp2) { 85 | return sp1.top() <= sp2.bottom() && sp1.bottom() >= sp2.top(); 86 | } 87 | 88 | static boolean overlap(Sprite sp1, Sprite sp2) { 89 | boolean inx = overlapx(sp1,sp2); 90 | boolean iny = overlapy(sp1,sp2); 91 | return inx && iny; 92 | } 93 | 94 | private Picture p; 95 | private double velx, vely, x, y; 96 | private boolean active = true; 97 | private int drawingPriority; 98 | private CollisionEventType inWall; 99 | 100 | public int getDrawingPriority() { 101 | return drawingPriority; 102 | } 103 | /** 104 | * The image with the lowest drawing priority 105 | * is drawn first. Give the highest number to 106 | * images you wish to be on top. 107 | * @param dp 108 | */ 109 | public void setDrawingPriority(int dp) { 110 | drawingPriority = dp; 111 | } 112 | 113 | /** 114 | * Used for detecting collisions 115 | */ 116 | int yindex; 117 | 118 | public boolean isActive() { return active; } 119 | public void destroy() { active = false; } 120 | 121 | public void setPicture(Picture new_p) { 122 | if (new_p == null) { 123 | throw new NullPointerException("Can't set a null picture"); 124 | } 125 | double delx = p == null ? 0 : new_p.getWidth() - p.getWidth(); 126 | double dely = p == null ? 0 : new_p.getHeight() - p.getHeight(); 127 | this.p = new_p; 128 | setX(getX() - delx/2); 129 | setY(getY() - dely/2); 130 | if(!added) { 131 | scene.addSprite(this); 132 | added = true; 133 | } 134 | } 135 | public Picture getPicture() { return p; } 136 | public void setX(double x) { this.x = x; } 137 | public void setCenterX(double x) { this.x = x - getWidth()/2; } 138 | public void setCenterY(double y) { this.y = y - getHeight()/2; } 139 | public double getCenterX() { return x + getWidth()/2; } 140 | public double getCenterY() { return y + getHeight()/2; } 141 | 142 | public double getX() { return x; } 143 | public void setY(double y) { this.y = y; } 144 | public double getY() { return y; } 145 | public void setHeadingOffset(double h) { 146 | heading = heading + headingOffset - this.headingOffset; 147 | headingOffset = h; 148 | } 149 | public double getHeading() { return heading; } 150 | public double getSpeed() { 151 | return Math.sqrt(velx*velx+vely*vely); 152 | } 153 | public void rotate(double th) { 154 | heading += th; 155 | double sp = getSpeed(); 156 | setVel(sp*Math.cos(heading),sp*Math.sin(heading)); 157 | } 158 | public double getHeadingOffset() { return headingOffset; } 159 | public void setForwardDirection(double velx, double vely) { 160 | this.headingOffset = Math.atan2(vely,velx)-heading; 161 | } 162 | public void setVel(double velx, double vely) { 163 | this.velx = velx; 164 | this.vely = vely; 165 | if(velx != 0 || vely != 0) { 166 | this.heading = Math.atan2(vely,velx); 167 | } 168 | } 169 | public double getVelX() { return velx; } 170 | public void setVelY(double vely) { this.vely = vely; } 171 | public double getVelY() { return vely; } 172 | 173 | public double getWidth() { 174 | return p.getWidth(); 175 | } 176 | public double getHeight() { 177 | return p.getHeight(); 178 | } 179 | 180 | void move(Dimension d) { 181 | moveTo(); 182 | x += velx; 183 | y += vely; 184 | boolean invis = false; 185 | boolean xlo=false, xhi=false, ylo=false, yhi=false; 186 | if(this.scene.periodic_x || this.scene.periodic_y) { 187 | Picture bg = this.scene.background; 188 | if (bg != null) { 189 | Dimension full = bg.getSize(); 190 | if (this.scene.periodic_x) { 191 | if (x > full.width) { 192 | x -= full.width; 193 | } else if (x < 0) { 194 | x += full.width; 195 | } 196 | } 197 | if (this.scene.periodic_y) { 198 | if (y > full.height) { 199 | y -= full.height; 200 | } else if (y < 0) { 201 | y += full.height; 202 | } 203 | } 204 | } 205 | } 206 | 207 | if (!this.scene.periodic_x) { 208 | if (x < -getWidth()) { 209 | xlo = true; 210 | invis = true; 211 | } else if (x < 0 && velx < 0) { 212 | xlo = true; 213 | } 214 | 215 | if (x > d.width) { 216 | xhi = true; 217 | invis = true; 218 | } else if (x + getWidth()> d.width && velx > 0) { 219 | xhi = true; 220 | } 221 | } 222 | 223 | if (!this.scene.periodic_y) { 224 | if (y < -getHeight()) { 225 | ylo = true; 226 | invis = true; 227 | } else if (y < 0 && vely < 0) { 228 | ylo = true; 229 | } 230 | 231 | if (y > d.height) { 232 | yhi = true; 233 | invis = true; 234 | } else if (y + getHeight() > d.height && vely > 0) { 235 | yhi = true; 236 | } 237 | } 238 | 239 | if(xlo || xhi || ylo || yhi) { 240 | CollisionEventType eventType = CollisionEventType.WALL; 241 | // Check inWall == null to ensure that first we get a 242 | // collision type of WALL then a type of inWall. 243 | if (invis && inWall != null) { 244 | eventType = CollisionEventType.WALL_INVISIBLE; 245 | } 246 | if (eventType != inWall) { 247 | doProcessEvent(new SpriteCollisionEvent(xlo, xhi, ylo, yhi, eventType)); 248 | inWall = eventType; 249 | } 250 | } else { 251 | inWall = null; 252 | } 253 | } 254 | 255 | /** 256 | * Override this method to determine how the sprite 257 | * will react when it collides with another sprite 258 | * or with the boundaries of the screen. 259 | * @param ev 260 | */ 261 | public void processEvent(SpriteCollisionEvent ev) { 262 | } 263 | 264 | @Override 265 | public void mouseClicked(MouseEvent e) { 266 | } 267 | 268 | @Override 269 | public void mousePressed(MouseEvent e) { 270 | } 271 | 272 | @Override 273 | public void mouseReleased(MouseEvent e) { 274 | } 275 | 276 | @Override 277 | public void mouseEntered(MouseEvent e) { 278 | } 279 | 280 | @Override 281 | public void mouseExited(MouseEvent e) { 282 | } 283 | 284 | boolean moveToEnabled = false; 285 | double moveToX, moveToY, moveToSpeed; 286 | public void moveTo(double destX,double destY,double speed) { 287 | moveToX = destX - getWidth()/2; 288 | moveToY = destY - getHeight()/2; 289 | moveToSpeed = speed; 290 | moveToEnabled = true; 291 | double xv = getX(), yv = getY(); 292 | double delx = moveToX-xv, dely = moveToY-yv; 293 | double theta = Math.atan2(dely, delx); 294 | setVel(speed * Math.cos(theta), speed * Math.sin(theta)); 295 | assert speed > 0; 296 | } 297 | public boolean moveToEnabled() { 298 | return moveToEnabled; 299 | } 300 | 301 | public void arrived() {} 302 | 303 | public void moveTo() { 304 | if(moveToEnabled) { 305 | double xv = getX(), yv = getY(); 306 | double delx = moveToX-xv, dely = moveToY-yv; 307 | double r = Math.sqrt(delx*delx+dely*dely); 308 | if(r < moveToSpeed*2) { 309 | setX(moveToX); 310 | setY(moveToY); 311 | setVel(0,0); 312 | moveToEnabled = false; 313 | arrived(); 314 | } else { 315 | // double theta = Math.atan2(dely, delx); 316 | // setVelX(moveToSpeed * Math.cos(theta)); 317 | // setVelY(-moveToSpeed * Math.sin(theta)); 318 | } 319 | } 320 | } 321 | 322 | /** 323 | * Block legacy methods. 324 | */ 325 | final public void processEvent() {} 326 | final public void preMove() {} 327 | final public void postMove() {} 328 | 329 | final private LinkedList events = new LinkedList<>(); 330 | private boolean running; 331 | 332 | /** 333 | * This method serializes the events, preventing them happening all 334 | * at once. 335 | * @param spriteCollisionEvent 336 | */ 337 | private void doProcessEvent(SpriteCollisionEvent spriteCollisionEvent) { 338 | synchronized(events) { 339 | if(running) { 340 | events.addLast(spriteCollisionEvent); 341 | return; 342 | } else { 343 | running = true; 344 | } 345 | } 346 | while(true) { 347 | processEvent(spriteCollisionEvent); 348 | synchronized(events) { 349 | if(events.isEmpty()) { 350 | running = false; 351 | break; 352 | } else { 353 | spriteCollisionEvent = events.removeFirst(); 354 | } 355 | } 356 | } 357 | } 358 | 359 | @Override 360 | public int compareTo(Sprite that) { 361 | int r = this.drawingPriority - that.drawingPriority; 362 | if(r == 0) 363 | r = System.identityHashCode(this) - System.identityHashCode(that); 364 | return r; 365 | } 366 | 367 | AffineTransform getTransform(AffineTransform old, int tx,int ty) { 368 | AffineTransform af = new AffineTransform(old); 369 | af.translate(getX()+tx,getY()+ty); 370 | if(freezeOrientation) 371 | return af; 372 | af.rotate(heading+headingOffset, getWidth()/2, getHeight()/2); 373 | return af; 374 | } 375 | 376 | public Scene migrate(Scene scene2, double x, double y, double vx, double vy) { 377 | SpriteComponent sc = scene.getSpriteComponent(); 378 | Scene oldScene = sc.swapScene(scene2); 379 | scene.sprites.remove(this); 380 | scene2.sprites.add(this); 381 | scene = scene2; 382 | this.x = x; 383 | this.y = y; 384 | this.velx = vx; 385 | this.vely = vy; 386 | return oldScene; 387 | } 388 | } 389 | --------------------------------------------------------------------------------