傾斜プラクティス ver.3 当たり判定付き
当たり判定と、パーティクルごとのHitPointを付けた。
今回は当たり判定回りを見たいので地形は表示しないようにした。
パーティクルは、黄色と水色に分けていて、
違う色同士が当たる(赤い×)と運動エネルギーの小さい方のHPが削られる。
当たり判定そのものは同色間にもある。
HPが0になるときえて、その場所に一瞬墓標(青い+)が立ちますw
当たり判定は、フレーム毎に各パーティクルあたりx座標が一番近い一つだけ判定している。
(PC側AIとかはまあ別として)同色同士が群れるようにして、ユーザ操作で地形に手を加えられるようにしたらゲーム風にできるかな?
/**
* Copyright lagash ( http://wonderfl.net/user/lagash )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/4vYP
*/
// forked from dalmacija's 傾斜プラクティス ver.2
// 当たり判定と、パーティクルごとのHitPointを付けた。
// 今回は当たり判定回りを見たいので地形は表示しないようにした。
// パーティクルは、黄色と水色に分けていて、
// 違う色同士が当たる(赤い×)と運動エネルギーの小さい方のHPが削られる。
// 当たり判定そのものは同色間にもある。
// HPが0になるときえて、その場所に一瞬墓標(青い+)が立ちますw
// 当たり判定は、フレーム毎に各パーティクルあたりx座標が一番近い一つだけ判定している。
// (PC側AIとかはまあ別として)同色同士が群れるようにして、ユーザ操作で地形に手を加えられるようにしたらゲーム風にできるかな?
//
package {
import flash.display.Sprite;
import flash.display.Shape;
import flash.display.Bitmap;
import flash.display.Stage;
import flash.display.BitmapData;
import flash.display.DisplayObjectContainer;
import flash.display.LineScaleMode;
import flash.display.BlendMode;
import flash.events.MouseEvent;
import flash.filters.DisplacementMapFilter;
import flash.geom.Matrix;
import flash.geom.Rectangle;
import flash.geom.Point;
import flash.geom.ColorTransform;
import flash.events.Event;
import flash.text.TextField;
import flash.utils.ByteArray;
import flash.filters.BlurFilter;
import net.hires.debug.Stats;
public class partest extends Sprite {
var shape1:Shape;
var shape2:Shape;
var tmpBmd:BitmapData;
var bmp:Bitmap;
var bmp2:Bitmap;
var curves:Object;
var rotationColor:Number;
var baseMatrix: Matrix = new Matrix(); //var stg:DisplayObjectContainer;
var baseRect:Rectangle;
var basePoint:Point;
var baseColorTransform:ColorTransform;
var keishaMap:BitmapData;
const maxParticles = 1000;
static public var forceMap: BitmapData;
private var COLOR: uint = 0xFFFFFF;
private var seed: int;
private var mw: int;
private var mh: int;
private var arr: Array;
private var point: Point;
private var point2: Point;
private var colorTf: ColorTransform;
private var blur: BlurFilter;
private var vecMap:Array;
static public const _TABLE_SIZE:int = 0x10000;
static public const _PI:Number = Math.PI;
static public const _TWO_PI:Number = 2 * _PI;
static public const _TWO_PI_SCALE:Number = _TABLE_SIZE / _TWO_PI;
static public const _HALF_PI:Number = _PI / 2;
static public const _table:Vector.<Number> = new function ():Vector.<Number>{
var table:Vector.<Number> = new Vector.<Number>(_TABLE_SIZE, true);
for (var i:uint = 0; i < _TABLE_SIZE; i++) {
table[i] = Math.sin(i / _TWO_PI_SCALE);
}
return table;
};
static public var stageWidth;
static public var stageHeight;
var centerX:uint;
var centerY:uint;
private var particles:Vector.<particle>=new Vector.<particle>();
private var sidesVec=particles;
private var textDisp:TextField;
public function partest() {
super();
addEventListener(Event.ADDED_TO_STAGE, addToStageHandlr);
}
private function addToStageHandlr(e:Event) {init();setMap();}
private function init() {
stage.frameRate = 60;
stageWidth = stage.stageWidth;
stageHeight = stage.stageHeight;
bmp = new Bitmap(new BitmapData(stage.stageWidth, stage.stageHeight, true, 0xff000000), "auto", true);//bitmap処理用
bmp.alpha = 1;
bmp2 = new Bitmap(new BitmapData(stage.stageWidth, stage.stageHeight, true, 0xff000000), "auto", true);//bitmap処理用
textDisp = new TextField();
textDisp.width=stage.stageWidth;
textDisp.y = stage.stageHeight-20;
textDisp.textColor = 0xffffff;
basePoint = new Point(0, 0);
baseRect = new Rectangle(0, 0, stageWidth, stageHeight);
baseColorTransform = new ColorTransform;
baseColorTransform.redOffset = baseColorTransform.greenOffset = baseColorTransform.blueOffset = -10;
forceMap = new BitmapData(stageWidth / 2, stageHeight / 2);
baseMatrix.identity();
stage.addEventListener(MouseEvent.CLICK, mouseClickHandlr);
stage.addEventListener(Event.ENTER_FRAME, enterframeHandlr);
//addChild(bmp2);
addChild(bmp);
addChild(new Stats());
addChild(textDisp);
var sidePer=0;
if(sidesVec){
var tmpYellow=sidesVec.length;
var tmpCyan=particles.length-sidesVec.length;
sidePer=(tmpCyan-tmpYellow)/2;
}
var currentParticlesLength=particles.length;
for (var i = 0; i < maxParticles-currentParticlesLength; i++) {
if (i != 0) {
particles.push(new particle(stage.stageWidth * Math.random(), stage.stageHeight * Math.random(), particles.length, particles[particles.length - 1]));
}else {
particles.push(new particle(stage.stageWidth * Math.random(), stage.stageHeight * Math.random(), 0));
}
particles[particles.length-1].side = (particles[particles.length-1].yy<stage.stageHeight/2+sidePer)?true:false;
}
}
private function mouseClickHandlr(e) {
setMap();
}
function setMap():void{
forceMap.perlinNoise(mw = forceMap.width >> 2, mh = forceMap.height >> 2, 1,
seed = Math.random() * 0xFFFF, true, true, 1,true);
arr = [point = new Point(), point2 = new Point()];
keishaMap = new BitmapData(stage.stageWidth, stage.stageHeight, true, 0x00000000);//傾斜データ保存用
}
function setMapPoint(tmpX,tmpY):uint{
var col = forceMap.getPixel(tmpX >> 1, tmpY >> 1);
var dx = 0;
var dy = 0;
for (var py = -1; py < 2; py++){
for (var px = -1; px < 2; px++) {
if (px == 0 && py == 0) continue;
var ppx = tmpX + px;
var ppy = tmpY + py;
if (ppx < 0 || ppx >= stageWidth) { ppx = int(ppx<0)* (stageWidth-1); }
if (ppy < 0 || ppy >= stageHeight){ ppy = int(ppy<0)* (stageHeight-1);}
var tmpcol = forceMap.getPixel(ppx >> 1, ppy >> 1);
//bmp2.bitmapData.setPixel(ppx, ppy, tmpcol);
if (px*px + py*py == 1) {
dx += (col - tmpcol) * px;
dy += (col - tmpcol) * py;
}else {
dx += (col - tmpcol) * px*.7;
dy += (col - tmpcol) * py*.7;
}
}
}
bmp2.bitmapData.setPixel(tmpX, tmpY, col);
col = uint((uint((uint(dx/5)&0x80000000)>>>16)+(uint(dx/5)&0x7fff)<<16)+uint((uint(dy/5) & 0x80000000) >>> 16) + (uint(dy/5) & 0x7fff));
keishaMap.setPixel32(tmpX, tmpY, col);
return col;
}
private function enterframeHandlr(e)
{
var flg_2 = 0;
bmp.bitmapData.lock();
centerX = centerY = 0;
var col: uint, h: Number;
sidesVec=particles.filter(sideCheck,null);
function sideCheck(item:particle, index:int, vector:Vector.<particle>):Boolean {
if (item.side==false) { return false; }
return true;
}
particles.sort(sortParticles);
function sortParticles(x, y):Number {
if (x.xx > y.xx) { return 1; } else { return -1; }
return 0;
}
var tmpTx = 0; var tmpTy = 0;
for (var i = 0; i < particles.length; i++) {
var tmpObj = particles[i];
if (i != 0) {
var hitcnt = i;
while (hitcnt) {
hitcnt--;
if ( tmpObj.xx - particles[hitcnt].xx > 1) {
break;
}
if( Math.abs(tmpObj.yy - particles[hitcnt].yy) < 1) {
var tmpCol=0xffffff;
if(tmpObj.side!=particles[hitcnt].side){
var dm = tmpObj.getTl() - particles[hitcnt].getTl();
if (dm > 0) { particles[hitcnt].hp -= dm; } else { tmpObj.hp += dm; }
tmpCol=0xff0000;
}
for (var exp = 1; exp < 4;exp++){
bmp.bitmapData.setPixel(tmpObj.xx - exp, tmpObj.yy-exp, tmpCol );
bmp.bitmapData.setPixel(tmpObj.xx + exp, tmpObj.yy+exp, tmpCol );
bmp.bitmapData.setPixel(tmpObj.xx-exp, tmpObj.yy + exp, tmpCol );
bmp.bitmapData.setPixel(tmpObj.xx+exp, tmpObj.yy - exp, tmpCol );
}
tmpTx = particles[hitcnt].tx;
tmpTy = particles[hitcnt].tx;
particles[hitcnt].tx += tmpObj.tx;
particles[hitcnt].ty += tmpObj.ty;
tmpObj.tx += tmpTx;
tmpObj.ty += tmpTy;
}
break;
}
}
centerX += tmpObj.xx;
centerY += tmpObj.yy;
var sideColor = 0xee * int(tmpObj.side);
col = 0xee;// * i / maxParticles;
col = (0x10000 * sideColor) + (0x100 * col) + (col-sideColor);
var tmpCol = keishaMap.getPixel32(tmpObj.xx, tmpObj.yy);
if (forceMap.getPixel(tmpObj.xx>>1, tmpObj.yy>>1)!=bmp2.bitmapData.getPixel(tmpObj.xx, tmpObj.yy)) tmpCol=setMapPoint(int(tmpObj.xx), int(tmpObj.yy));
var bX = tmpCol >>> 16;
var bY = tmpCol & 0xffff;
tmpObj.dx = int(uint((((bX&0x8000)<<16)>>16)+(bX&0x7fff)))*.00001;
tmpObj.dy = int(uint((((bY&0x8000)<<16)>>16)+(bY&0x7fff)))*.00001;
tmpObj.tx = tmpObj.tx * .99 + (tmpObj.dx * uint(tmpObj.dx > 0 && tmpObj.tx < 4) + tmpObj.dx * uint(tmpObj.dx<0 && tmpObj.tx>-4));
tmpObj.ty = tmpObj.ty * .99 + (tmpObj.dy * uint(tmpObj.dy > 0 && tmpObj.ty < 4) + tmpObj.dy * uint(tmpObj.dy<0 && tmpObj.ty>-4));
tmpObj.xx += tmpObj.tx;
tmpObj.yy += tmpObj.ty;
if (tmpObj.xx < 0 || tmpObj.xx >= stageWidth) { tmpObj.xx = uint(tmpObj.tx < 0) * (stageWidth-1);}
if (tmpObj.yy < 0 || tmpObj.yy >= stageHeight) { tmpObj.yy = uint(tmpObj.ty < 0) * (stageHeight-1);}
bmp.bitmapData.setPixel(tmpObj.xx, tmpObj.yy, col );
if (tmpObj.hp < 0) {
particles.splice(i, 1);
//trace(sidesVec.length+" , "+(particles.length-sidesVec.length));
textDisp.text="yellow:"+sidesVec.length+" / cyan: "+(particles.length-sidesVec.length);
//trace(i + " is dead! total: "+particles.length);
var ccc = 0x5555ff;//*int(tmpObj.side)
for ( exp = 1; exp < 30;exp++){
bmp.bitmapData.setPixel(tmpObj.xx - exp, tmpObj.yy, ccc );
bmp.bitmapData.setPixel(tmpObj.xx + exp, tmpObj.yy, ccc );
bmp.bitmapData.setPixel(tmpObj.xx, tmpObj.yy + exp, ccc );
bmp.bitmapData.setPixel(tmpObj.xx, tmpObj.yy - exp, ccc );
}
if(particles.length<200 || sidesVec.length<5 || particles.length-sidesVec.length<5)init();
}
}
centerX /= particles.length;
centerY /= particles.length;
//スクロール処理
//bmp.bitmapData.colorTransform(baseRect, baseColorTransform);
//bmp2.bitmapData.applyFilter(bmp2.bitmapData, baseRect, basePoint, new DisplacementMapFilter(bmp.bitmapData));
//bmp.bitmapData.scroll((stageWidth / 2 - centerX) / 10, (stageHeight / 2 - centerY) / 10);
//bmp.bitmapData.scroll(_table[((frameCounter + _HALF_PI) * _TWO_PI_SCALE) & (_TABLE_SIZE - 1)] * 10, _table[(frameCounter * _TWO_PI_SCALE) & (_TABLE_SIZE - 1)] * 10);
//tmpBmd.colorTransform(baseRect, baseColorTransform);
//tmpBmd.scroll( -(stageWidth / 2 - centerX) / 5, -(stageHeight / 2 - centerY) / 5);
if (Math.abs((stageWidth / 2 - centerX) / 10) > 1 || Math.abs((stageHeight / 2 - centerY) / 10) > 1) {
point.x -=(stageWidth / 2 - centerX) / 10;
point2.y -=(stageHeight / 2 - centerY) / 10;
forceMap.perlinNoise(mw, mh, 1, seed, true, true, 1, true, arr);
}
//bmp.bitmapData.draw(shape1,baseMatrix, null, BlendMode.LIGHTEN);
//bmp.bitmapData.draw(shape2,baseMatrix, null, BlendMode.ADD);
//bmp.bitmapData.copyPixels(tmpBmd, baseRect, basePoint, tmpBmd, new Point(0, 0), true);
bmp.bitmapData.applyFilter(bmp.bitmapData, baseRect, basePoint,new BlurFilter(2,2,1));
//bmp2.bitmapData.applyFilter(bmp.bitmapData, baseRect, basePoint,new BlurFilter(2,2,1));
//bmp.bitmapData.draw(shape1,baseMatrix, null, BlendMode.OVERLAY);
bmp.bitmapData.unlock();
/*
//パーティクル追加
if (!flg && flg_2==0 || (mouse_X<0 || mouse_X>stageWidth || mouse_Y<0 || mouse_Y>stageHeight)) return;
if (particles.length > 0) {
//if (getLineLength(new Rectangle(particles[particles.length - 1].xx, particles[particles.length - 1].yy, mouse_X, mouse_Y)) < 3) { ; return false; }
do{
var newX = mouse_X + (Math.random() * 100-50) * flg_2;
var newY = mouse_Y + (Math.random() * 100-50) * flg_2;
}while (newX<0 || newX>stageWidth || newY<0 || newY>stageHeight);
particles.push(new particle(newX,newY, particles.length, particles[particles.length-1]));
particles[0].setObj(particles[particles.length-1]);
} else {
particles.push(new particle(mouse_X,mouse_Y,0));
}
if (particles.length > maxParticles) {
particles.shift();
}
*/
}
function getLineLength(p:Rectangle):Number
{
var vx=p.x-p.width;
var vy=p.y-p.height;
var vl=Math.sqrt(Math.pow(vx,2)+Math.pow(vy,2));
return vl;
}
function getLine(p:Rectangle):Point
{
var vx=p.x-p.width;
var vy=p.y-p.height;
var ts=new Point();
ts.x=vy/vx;
ts.y=p.height-ts.x*p.width;
return ts;
}
function getCrossLine(p:Rectangle):Point
{
var vx=p.x-p.width;
var vy=p.y-p.height;
var ts=new Point();
ts.x=-vx/vy;
ts.y=p.y-ts.x*p.x;
return ts;
}
function clone( arg:* ) :*
{
var myBA:ByteArray = new ByteArray();
myBA.writeObject(arg);
myBA.position = 0;
return( myBA.readObject() );
}
}
}
class particle{
//var col:uint = 0;
//var ox:Number=0;
//var oy:Number=0;
//var ol:Number=0;
var xx:Number=0;
var yy:Number=0;
//var _x:Number=0;
//var _y:Number=0;
var tx:Number=0;
var ty:Number=0;
var dx:Number=0;
var dy:Number=0;
var dl:Number = 0;
//var M:Number=1;
//var cnt:Number=0;
//var obj:particle;
//var cut:Boolean = false;
//var mv:uint;
//var name:String;
var hp:int;
var side:Boolean;
public function particle(... args):void {
//ox= xx = args[0];
//oy= yy = args[1];
xx = args[0];
yy = args[1];
//name = args[2];
//obj = args[3];
//if (args[3]==undefined)obj = this;
//var tmptime = new Date();
//cnt = tmptime.milliseconds * .002 * Math.PI;
tx = 0;// partest._table[((cnt + partest._HALF_PI) * partest._TWO_PI_SCALE) & (partest._TABLE_SIZE - 1)];
ty = 0;// partest._table[(cnt * partest._TWO_PI_SCALE) & (partest._TABLE_SIZE - 1)];
//col = Math.random() * 16777215;
hp = 10;
}
public function getTl():Number {
return Math.sqrt(Math.pow(tx,2)+Math.pow(ty,2));
}
/*public function setObj(o):void {
obj = o;
}
public function setMass(m):void {
M = m;
}*/
}