using System; using System.Collections.Generic; using System.Text; using CommonLang; using CommonUI.Display; namespace CommonUI.Cell.Game { public class CCD { public enum CDType : byte { CD_TYPE_RECT = 1, CD_TYPE_LINE = 2, CD_TYPE_POINT = 3, } public CDType Type = CDType.CD_TYPE_RECT; public int Mask; /// /// Left /// public float X1; /// /// Top /// public float Y1; /// /// Right /// public float X2; /// /// Bottom /// public float Y2; public CCD() { } public CCD(CCD theobj) { this.Type = theobj.Type; this.Mask = theobj.Mask; this.X1 = theobj.X1; this.Y1 = theobj.Y1; this.X2 = theobj.X2; this.Y2 = theobj.Y2; } public float Width { get { return X2 - X1; } } public float Height { get { return Y2 - Y1 + 1; } } /// /// 得到外包矩形中心点和渲染中心点的偏移 /// public float MedianY { get { return -(Height / 2 - (Y1 + Height)); } } /// /// 得到外包矩形中心点和渲染中心点的偏移 /// public float MedianX { get { return -(Width / 2 - (X1 + Width)); } } static public CCD CreateCDRect(int mask, float x, float y, float w, float h) { CCD ret = new CCD(); ret.Type = CDType.CD_TYPE_RECT; ret.Mask = mask; ret.X1 = x; ret.Y1 = y; ret.X2 = (x + w); ret.Y2 = (y + h); return ret; } static public CCD CreateCDRect_2Point(int mask, float sx, float sy, float dx, float dy) { CCD ret = new CCD(); ret.Type = CDType.CD_TYPE_RECT; ret.Mask = mask; ret.X1 = Math.Min(sx, dx); ret.Y1 = Math.Min(sy, dy); ret.X2 = Math.Max(sx, dx); ret.Y2 = Math.Max(sy, dy); return ret; } static public CCD CreateCDLine(int mask, float px, float py, float qx, float qy) { CCD ret = new CCD(); ret.Type = CDType.CD_TYPE_LINE; ret.Mask = mask; ret.X1 = px; ret.Y1 = py; ret.X2 = qx; ret.Y2 = qy; return ret; } } public class CGroup { internal short[][] Frames; internal int SubIndex=0; internal int SubCount=0; internal float w_left = 0; internal float w_top = 0; internal float w_bottom = 1; internal float w_right = 1; internal float w_width = 0; internal float w_height = 0; protected void fixArea(float left, float top, float right, float botton) { if (left < w_left) w_left = (short)left; if (top < w_top) w_top = (short)top; if (right > w_right) w_right = (short)right; if (botton > w_bottom) w_bottom = (short)botton; w_width = (short)(w_right - w_left); w_height = (short)(w_bottom - w_top); } static public bool touchArea( CGroup c1, int x1, int y1, CGroup c2, int x2, int y2) { if (CMath.intersectRect( x1 + c1.w_left, y1 + c1.w_top, x1 + c1.w_right, y1 + c1.w_bottom, x2 + c2.w_left, y2 + c2.w_top, x2 + c2.w_right, y2 + c2.w_bottom)) { return true; } return false; } public CCD getAllBounds() { CCD outcd = new CCD(); outcd.X1 = w_left; outcd.X2 = w_right; outcd.Y1 = w_top; outcd.Y2 = w_bottom; return outcd; } public void setFrames(short[][] frames) { Frames = frames; } public short[][] getFrames() { return Frames; } public void setComboFrame(short[] frame, int index) { Frames[index] = frame; } public int getCount() { return Frames.Length; } public int getComboFrameCount(int index) { return Frames[index].Length; } } public class CCollides : CGroup { internal CCD[] cds; public CCollides(int cdCount) { SubCount = cdCount; cds = new CCD[cdCount]; } private void setCD(int i, CCD cd) { if (i >= SubCount) { return; } cds[i] = cd; fixArea(cd.X1, cd.Y1, cd.X2, cd.Y2); } public void setCDRect(int i, int mask, float x, float y, float w, float h) { setCD(i, CCD.CreateCDRect(mask, x, y, w, h)); } public void setCDLine(int i, int mask, float px, float py, float qx, float qy) { setCD(i, CCD.CreateCDLine(mask, px, py, qx, qy)); } public CCD getCD(int index) { if (index < SubCount) { return cds[index]; } return null; } public CCD getFrameCD(int frame, int sub) { return getCD(Frames[frame][sub]); } } public class CAnimates : CGroup { internal CPJAtlas tiles; internal int[] STileID; internal Trans[] SFlip; internal float[] SX; internal float[] SY; internal float[] SW; internal float[] SH; internal float[] SAlpha; internal float[] SRotate; internal float[] SScaleX; internal float[] SScaleY; internal bool ComplexMode; public CAnimates(int partCount, CPJAtlas tils) { tiles = tils; SubCount = partCount; STileID = new int[partCount]; SFlip = new Trans[partCount]; SW = new float[partCount]; SH = new float[partCount]; SX = new float[partCount]; SY = new float[partCount]; SAlpha = new float[partCount]; SRotate = new float[partCount]; SScaleX = new float[partCount]; SScaleY = new float[partCount]; } public void setPart(int SubIndex, float px, float py, int tileid, Trans trans, float alpha = 1f, float rotate = 0, float scaleX = 1f, float scaleY = 1f) { if (SubIndex >= SubCount) { return; } STileID[SubIndex] = tileid; SW[SubIndex] = tiles.getWidth(tileid); SH[SubIndex] = tiles.getHeight(tileid); SX[SubIndex] = px; SY[SubIndex] = py; SFlip[SubIndex] = trans; SAlpha[SubIndex] = alpha; SRotate[SubIndex] = rotate; SScaleX[SubIndex] = scaleX; SScaleY[SubIndex] = scaleY; switch (trans) { case Trans.TRANS_NONE: case Trans.TRANS_ROT180: case Trans.TRANS_MIRROR: case Trans.TRANS_MIRROR_ROT180: SW[SubIndex] = tiles.getWidth(tileid); SH[SubIndex] = tiles.getHeight(tileid); break; case Trans.TRANS_ROT90: case Trans.TRANS_ROT270: case Trans.TRANS_MIRROR_ROT90: case Trans.TRANS_MIRROR_ROT270: SW[SubIndex] = tiles.getHeight(tileid); SH[SubIndex] = tiles.getWidth(tileid); break; } fixArea(SX[SubIndex], SY[SubIndex], SX[SubIndex] + SW[SubIndex], SY[SubIndex] + SH[SubIndex]); if (rotate != 0 || scaleX != 1f || scaleY != 1f) { ComplexMode = true; } } public CPJAtlas getTiles() { return tiles; } public int getFrameTileID(int frame, int sub) { return STileID[Frames[frame][sub]]; } public float getFrameX(int frame, int sub) { return SX[Frames[frame][sub]]; } public float getFrameY(int frame, int sub) { return SY[Frames[frame][sub]]; } public float getFrameW(int frame, int sub) { return SW[Frames[frame][sub]]; } public float getFrameH(int frame, int sub) { return SH[Frames[frame][sub]]; } public Trans getFrameTransform(int frame, int sub) { return SFlip[Frames[frame][sub]]; } public float getFrameAlpha(int frame, int sub) { return SAlpha[Frames[frame][sub]]; } public CCD getFrameBounds(int frame) { float left = float.MaxValue; float right = float.MinValue; float top = float.MaxValue; float bottom = float.MinValue; for (int i = SubCount; i >= 0; --i) { left = Math.Min(getFrameX(frame, i), left); right = Math.Max(getFrameX(frame, i) + getFrameW(frame, i), right); top = Math.Min(getFrameY(frame, i), top); bottom = Math.Max(getFrameY(frame, i) + getFrameH(frame, i), bottom); } CCD cd = CCD.CreateCDRect_2Point(0, left, top, right - left, bottom - top); return cd; } public void beginImage(Graphics g) { tiles.begin(g); } public void addVertex(VertexBuffer vertex, int index, float dx, float dy) { if (!ComplexMode) { for (int i = Frames[index].Length - 1; i >= 0; --i) { int idx = Frames[index][i]; uint rgba = Color.COLOR_WHITE; if (SAlpha[idx] != 1) { rgba = Color.toRGBA(0xFFFFFF, Math.Min((int)(SAlpha[idx] * 255), 255)); } tiles.addVertex(vertex, STileID[idx], SX[idx] + dx, SY[idx] + dy, SFlip[idx], rgba); } } else { vertex.translate(dx, dy); for (int i = Frames[index].Length - 1; i >= 0; --i) { int idx = Frames[index][i]; float tx = SW[idx] / 2.0f; float ty = SH[idx] / 2.0f; uint rgba = Color.COLOR_WHITE; if (SAlpha[idx] != 1) { rgba = Color.toRGBA(0xFFFFFF, Math.Min((int)(SAlpha[idx] * 255), 255)); } vertex.pushTransform(); vertex.translate(SX[idx] + tx, SY[idx] + ty); vertex.rotate(SRotate[idx]); vertex.scale(SScaleX[idx], SScaleY[idx]); tiles.addVertex(vertex, STileID[idx], -tx, -ty, SFlip[idx], rgba); vertex.popTransform(); } vertex.translate(-dx, -dy); } } public void render(Graphics g, int index, float dx = 0, float dy = 0) { if (!ComplexMode) { for (int i = Frames[index].Length - 1; i >= 0; --i) { int idx = Frames[index][i]; g.addAlpha(SAlpha[idx]); tiles.render(g, STileID[idx], SX[idx] + dx, SY[idx] + dy, SFlip[idx]); } } else { g.translate(dx, dy); for (int i = Frames[index].Length - 1; i >= 0; --i) { int idx = Frames[index][i]; float tx = SW[idx] / 2.0f; float ty = SH[idx] / 2.0f; float olda = g.getAlpha(); g.addAlpha(SAlpha[idx]); g.pushTransform(); g.translate(SX[idx] + tx, SY[idx] + ty); g.rotate(SRotate[idx]); g.scale(SScaleX[idx], SScaleY[idx]); tiles.render(g, STileID[idx], -tx, -ty, SFlip[idx]); g.popTransform(); g.setAlpha(olda); } g.translate(-dx, -dy); } } } }