習作:ブロック崩し
♥0 |
Line 216 |
Modified 2012-11-26 21:44:10 |
MIT License
archived:2017-03-20 11:15:26
ActionScript3 source code
/**
* Copyright fumix ( http://wonderfl.net/user/fumix )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/bCOq
*/
package {
import flash.display.Sprite;
import flash.display.StageAlign;
import flash.display.StageScaleMode;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.text.TextField;
import flash.text.TextFieldAutoSize;
import flash.utils.getTimer;
public class Game extends Sprite {
private var _ball : Sprite;
private var _ballSpeed : Number;
private var _ballSpeedX : Number;
private var _ballSpeedY : Number;
private var _tickBefore:Number;
private var _scoreTextField : TextField;
private var _score : int;
private var _bar : Sprite;
private var _blocks : Array;
private var _firstBlocks : Blocks;
private var _bleakBlockCount : int;
public function Game() : void {
if (stage) _initialize();
else addEventListener(Event.ADDED_TO_STAGE, _initialize);
}
/**
* _initialize
*/
private function _initialize(e : Event = null) : void {
removeEventListener(Event.ADDED_TO_STAGE, _initialize);
stage.scaleMode = StageScaleMode.NO_SCALE;
stage.align = StageAlign.TOP_LEFT;
// ボール
_ball = new Sprite();
_ball.graphics.beginFill(0xFF0000);
_ball.graphics.drawCircle(0, 0, 8);
_ball.graphics.endFill();
addChild(_ball);
// ボール初期設定
_ballSpeed = 0.50;
_ballSpeedX = Math.cos(45 * Math.PI / 180) * _ballSpeed;
_ballSpeedY = Math.sin(45 * Math.PI / 180) * _ballSpeed;
_ball.x = 50;
_ball.y = 320;
// スコア
_scoreTextField = new TextField();
score = 10;
addChild(_scoreTextField);
// バー
_bar = new Sprite();
_bar.graphics.beginFill(0x999999);
_bar.graphics.drawRect(-40, -10, 80, 20);
_bar.graphics.endFill();
addChild(_bar);
_bar.y = 400;
// ブロック
_bleakBlockCount = 0;
var offsetX : int = 40+13;
var offsetY : int = 40;
var margin : int = 0;
var blockNo:int = 0;
var old:Blocks;
_blocks = new Array();
for (var dx : int = 0; dx < 14; dx++) {
for (var dy : int = 0; dy < 4; dy++) {
var block : Sprite = new Sprite();
block.graphics.lineStyle(1, 0x999999);
block.graphics.beginFill(0xCCCCCC);
block.graphics.drawRect(-13, -19, 27, 38);
block.graphics.endFill();
block.x = dx * block.width + offsetX + margin;
block.y = dy * block.height + offsetY + margin;
block.name = 'block'+blockNo;
//ナンバー
var tf:TextField = new TextField();
tf.selectable = false;
tf.autoSize = TextFieldAutoSize.LEFT;
tf.text = String(blockNo);
block.addChild(tf);
//ブロックをリンクリストに代入
var b:Blocks = new Blocks();
b.block = block;
_blocks.push(b);
if(_firstBlocks == null){
old = _firstBlocks = b;
}else{
old.next = b;
old = b;
}
addChild(block);
blockNo++;
}
}
stage.addEventListener(MouseEvent.MOUSE_DOWN, onStageMouseDown);
}
private function onStageMouseDown(event : MouseEvent) : void {
stage.removeEventListener(MouseEvent.MOUSE_DOWN, onStageMouseDown);
addEventListener(Event.ENTER_FRAME, _updateHandler);
stage.addEventListener(MouseEvent.MOUSE_DOWN, onStageMouseDownChangeFPS);
}
private function onStageMouseDownChangeFPS(event : MouseEvent) : void {
if(stage.frameRate < 60) {
stage.frameRate = 60;
}else{
stage.frameRate = 30;
}
}
private function _updateHandler(e : Event) : void {
_interaction();
_draw();
}
/**
* インタラクションの反映
*/
private function _interaction() : void {
// バーの移動アクション
moveBar();
// ボールの反射アクション
moveBall();
// ゲームエンド判定
checkGameEnd();
}
/**
* ゲームエンド判定
*/
private function checkGameEnd() : void {
//ブロック全部消せた?
if (_bleakBlockCount >= _blocks.length) {
removeEventListener(Event.ENTER_FRAME, _updateHandler);
//スコアがマイナス?
}else if(score < 0){
removeEventListener(Event.ENTER_FRAME, _updateHandler);
}
}
/**
* ボールの反射判定
*/
private function moveBall() : void {
//壁への反射判定
if (stage.stageWidth - _ball.width * 0.5 < _ball.x ) {
_ball.x = stage.stageWidth - _ball.width * 0.5;
_ballSpeedX = -_ballSpeedX;
}
if (_ball.width * 0.5 > _ball.x) {
_ball.x = _ball.width * 0.5;
_ballSpeedX = -_ballSpeedX;
}
if (stage.stageHeight - _ball.height * 0.5 < _ball.y ) {
_ball.y = stage.stageHeight - _ball.height * 0.5;
_ballSpeedY = -_ballSpeedY;
//下に逃した場合はスコアマイナス
score = score - 5;
}
if (_ball.height * 0.5 > _ball.y) {
_ball.y = _ball.height * 0.5;
_ballSpeedY = -_ballSpeedY;
}
//バーへの反射判定
if (_ball.hitTestObject(_bar)) {
if(_ball.y < _bar.y) {
_ball.y = _bar.y - _ball.height * 0.5 - _ball.height * 0.5;
}else{
_ball.y = _bar.y + _ball.height * 0.5 + _ball.height * 0.5;
}
var rad : Number = Math.atan2(_ball.y - _bar.y, _ball.x - _bar.x);
_ballSpeedX = Math.cos(rad) * _ballSpeed;
_ballSpeedY = Math.sin(rad) * _ballSpeed;
}
//ブロックへの反射判定
var b:Blocks = _firstBlocks;
var flg:Boolean = true;//ブロックの当たり判定は1個しかしない
do {
if(_ball.hitTestObject(b.block) && b.visible && flg){
//ブロックを非表示に
b.block.visible = false;
b.visible = false;
flg = false;
//スコアをアップ
score++;
//壊れたブロック数をカウントアップ
_bleakBlockCount++;
//左上に当たった場合
if(_ball.x < b.block.x-b.block.width * 0.5+_ball.width * 0.5 &&
_ball.y < b.block.y-b.block.height * 0.5+_ball.height * 0.5){
_ballSpeedX = -Math.cos(45 * Math.PI / 180) * _ballSpeed;
_ballSpeedY = -Math.sin(45 * Math.PI / 180) * _ballSpeed;
}
//右上に当たった場合
else if(_ball.x > b.block.x+b.block.width * 0.5-_ball.width * 0.5 &&
_ball.y < b.block.y-b.block.height * 0.5+_ball.height * 0.5){
_ballSpeedX = Math.cos(45 * Math.PI / 180) * _ballSpeed;
_ballSpeedY = -Math.sin(45 * Math.PI / 180) * _ballSpeed;
}
//左下に当たった場合
else if(_ball.x < b.block.x-b.block.width * 0.5+_ball.width * 0.5 &&
_ball.y > b.block.y+b.block.height * 0.5-_ball.height * 0.5){
_ballSpeedX = -Math.cos(45 * Math.PI / 180) * _ballSpeed;
_ballSpeedY = Math.sin(45 * Math.PI / 180) * _ballSpeed;
}
//右下に当たった場合
else if(_ball.x > b.block.x+b.block.width * 0.5-_ball.width * 0.5 &&
_ball.y > b.block.y+b.block.height * 0.5-_ball.height * 0.5){
_ballSpeedX = Math.cos(45 * Math.PI / 180) * _ballSpeed;
_ballSpeedY = Math.sin(45 * Math.PI / 180) * _ballSpeed;
}
//上に当たった場合
else if(_ball.y < b.block.y-b.block.height * 0.5+_ball.height * 0.5){
_ballSpeedY = -_ballSpeedY;
}
//下に当たった場合
else if(_ball.y > b.block.y+b.block.height * 0.5-_ball.height * 0.5){
_ballSpeedY = -_ballSpeedY;
}
//左に当たった場合
else if(_ball.x < b.block.y-b.block.width * 0.5+_ball.width * 0.5){
_ballSpeedX = -_ballSpeedX;
}
//右に当たった場合
else if(_ball.x > b.block.x+b.block.width * 0.5-_ball.width * 0.5){
_ballSpeedX = -_ballSpeedX;
}
}
} while (b = b.next);
}
/**
* バーの移動
*/
private function moveBar() : void {
_bar.x = mouseX;
}
/**
* 描画
*/
private function _draw() : void {
var tick: int = getTimer();
var t: int = tick - _tickBefore;
_tickBefore = tick;
_ball.x += _ballSpeedX*t;
_ball.y += _ballSpeedY*t;
}
public function get score() : int {
return _score;
}
public function set score(score : int) : void {
_score = score;
_scoreTextField.text = String(_score);
}
}
}
import flash.display.Sprite;
//ブロック配列用
class Blocks
{
public var visible:Boolean;
public var block:Sprite;
public var next:Blocks;
public function Blocks()
{
visible = true;
block = null;
}
}